从0开始回顾MySQL---系列四

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用系列 2核4GB
简介: 9、什么是回表(使用索引查询完整数据过程)?当我们需要查询一条完整的数据的时候:● 如果是通过聚簇索引来查询数据,例如 select * from user where id=100,那么此时只需要搜索聚簇索引的 B+Tree 就可以找到数据。● 如果是通过非聚簇索引来查询数据,例如 select * from user where username=zhangsan',那么此时需要先搜索 username 这一列索引的 B+树,搜索完成后得到主键的值,然后再去搜索聚簇索引的 B+树,就可以获取到一行完整的数据。对于第二种查询方式而言,一共搜索了两棵 B+树,第一次搜索 B+树 拿到

9、什么是回表(使用索引查询完整数据过程)?


当我们需要查询一条完整的数据的时候:

  • 如果是通过聚簇索引来查询数据,例如 select * from user where id=100,那么此时只需要搜索聚簇索引的 B+Tree 就可以找到数据。
  • 如果是通过非聚簇索引来查询数据,例如 select * from user where username=zhangsan',那么此时需要先搜索 username 这一列索引的 B+树,搜索完成后得到主键的值,然后再去搜索聚簇索引的 B+树,就可以获取到一行完整的数据。

对于第二种查询方式而言,一共搜索了两棵 B+树,第一次搜索 B+树 拿到主键值后再去搜索聚簇索引的 B+树,这个过程就是所谓的回表

10、回表的代价?


回表的代价:

  • 需要回表的记录越多,使用二级索引的性能就越低,甚至让某些查询宁愿使用全表扫描也不使用二级索引 。
  • 比方说 name 值在 Asa ~ Barlow 之间的用户记录数量占全部记录数量90%以上,那么如果使用 idx_name_birthday_phone_number 索引的话,有90%多的 id 值需要回表,这不是吃力不讨好么,还不如直接去扫描聚簇索引(也就是全表扫描)。

那什么时候采用全表扫描的方式,什么时候使用采用 二级索引 + 回表 的方式去执行查询呢?

  • 这个就是查询优化器做的工作,查询优化器会事先对表中的记录计算一些统计数据,然后再利用这些统计数据根据查询的 条件来计算一下需要回表的记录数,需要回表的记录数越多,就越倾向于使用全表扫描,反之倾向于使用 二级索引 + 回表 的方式。


11、非聚簇索引一定会回表查询吗?


不一定

  • 这涉及到查询语句所要求的字段是否全部命中了索引,如果全部命中了索引,那么就不必再进行回表查询。一个索引包含所有需要查询字段的值,被称之为"覆盖索引"。
  • 举个简单的例子,假设我们在学生表的成绩上建立了索引,那么当进行select score from student where score > 90的查询时,在索引的叶子节点上,已经包含了score 信息,不会再次进行回表查询。


12、联合索引是什么?为什么需要注意联合索引中的顺序?


MySQL可以使用多个字段同时建立一个索引,叫做联合索引。在联合索引中,如果想要命中索引,需要按照建立索引时的字段顺序挨个使用,否则无法命中索引。

具体原因为:

  • MySQL使用索引时需要索引有序,假设现在建立了"name,age,school"的联合索引,那么索引的排序为: 先按照name排序,如果name相同,则按照age排序,如果age的值也相等,则按照school进行排序。
  • 当进行查询时,此时索引仅仅按照name严格有序,因此必须首先使用name字段进行等值查询,之后对于匹配到的列而言,其按照age字段严格有序,此时可以使用age字段用做索引查找,以此类推。因此在建立联合索引的时候应该注意索引列的顺序,一般情况下,将查询需求频繁或者字段选择性高的列放在前面。此外可以根据特例的查询或者表结构进行单独的调整。

13、创建索引方式?


创建索引有三种方式

  1. 使用CREATE INDEX命令创建;
CREATE [UNIQUE|FULLTEXT] INDEX 索引名称 [USING 索引类型] ON 表名(列名...);
-- 索引类型默认是 B+TREE
  1. 使用ALTER TABLE命令去增加索引;
ALTER TABLE table_name ADD INDEX index_name (column_list);
  1. 在执行CREATE TABLE时创建索引 。
CREATE TABLEtable_name(
  c1 INT PRIMARY KEY,
  c2 INT NOT NULL,
  c3 INT NOT NULL,
  c4 VARCHAR(10),
  INDEX (c2,c3)  -- 创建两列c2和c3组成的索引。
);

14、创建索引的设计原则有哪些?


创建索引时的原则:

  1. 只为用于搜索、排序或分组的列创建索引:
  • 只为出现在 WHERE 子句中的列、连接子句中的连接列,或者出现在 ORDER BY 或 GROUP BY 子句中的列创建索引。而出现在查询列表中的列就没必要建立索引了。
  1. 为列的基数(区分度)大的列创建索引
  • 列的基数指的是某一列中不重复数据的个数,这个指标非常重要,直接影响我们是否能有效的利用索引。
  • 假设某个列的基数为 1 ,也就是所有记录在该列中的值都一样,那为该列建立索引是没有用的,因为所有值都一样就无法排序,无法进行快速查找。
  1. 索引列的类型尽量小
  • 数据类型越小,在查询时进行的比较操作越快(这是CPU层次的东东)
  • 数据类型越小,索引占用的存储空间就越少,在一个数据页内就可以放下更多的记录,从而减少磁盘 I/O 带来的性能损耗,也就意味着可以把更多的数据页缓存在内存中,从而加快读写效率。
  1. 可以只对字符串值的前缀建立索引
  • 对一个完整字符串建立索引时,字符串越长,在索引中占用的存储空间越大。
  • 可以只对字符串的前几个字符进行索引,既节约空间,又减少了字符串的比较时间,还大概能解决排序的问题。
  1. 让索引列在比较表达式中单独出现
  • 如果索引列在比较表达式中不是以单独列的形式出现,而是以某个表达式,或者函数调用形式出现的话,是用不到索引的。
  1. 使用短索引
  • 在给定大小的存储块内可以存储更多的索引值,相应的可以有效的提升 MySQL 访问索引的 I/O 效率。
  1. 让主键拥有 AUTO_INCREMENT 属性
  • 让主键具有 AUTO_INCREMENT ,让存储引擎自己为表生成主键,而不是我们手动插入,尽可能的减少页面分裂和记录移位。
  1. 尽量使用覆盖索引进行查询,避免回表带来的性能损耗。(一个索引包含(覆盖)所有需要查询字段的值,被称之为"覆盖索引")
  2. 其他:
  • 对于插入、更新、删除等 DML 操作比较频繁的表,不适合建立索引
  • 尽量的扩展索引,不要新建索引。比如表中已经有a的索引,现在要加(a,b)的索引,那么只需要修改原来的索引即可。

15、有哪些索引失效场景?


  1. 模糊搜索导致的索引失效
  • %放在匹配字段前是不走索引的,放在后面才会走索引。
  1. OR引起的索引失效
  • or语句前后没有同时使用索引,或者or前后连接的不是同一个字段。
  1. 运算符导致的索引失效
  • 如果你对列进行了(+,-,*,/,!), 那么都将不会走索引。
  1. 在索引字段上使用not,<>, ! =  (这样处理的是全表扫描)
  2. 类型不一致导致的索引失效
  • 比如列类型是字符串,一定要在条件中将数据用引号引用,否则失效(隐式转换类型)
  1. 函数导致的索引失效
  • 如果使用函数在索引列,这是不走索引的。
  1. NOT IN、NOT EXISTS、 in 、exists 导致索引失效


16、最左匹配原则?

概念:

  • 所谓最左原则指的就是如果你的 SQL 语句中用到了联合索引中的最左边的索引,那么这条 SQL 语句就可以利用这个联合索引去进行匹配,值得注意的是,当遇到范围查询(>、<、between、like)就会停止匹配。
  • 即最左优先,从左往右匹配,直到遇到范围查询,比如建立联合索引 (a,b,c),实际上是创建了三个索引,分别是(a)、(a,b)、(a,b,c)。索引是先根据a排序,a相同时b有序,a不同无序,以此类推,直到遇到范围查询(>、<、between、like)就会停止。

最左匹配的原理

假设,我们对(a,b)字段建立联合索引,那么如下图所示:

按照a来进行排序,在a相等的情况下,才按b来排序,因此a【2,4,4,7,8】是有序的,而b【4,1,3,6,7】是全局无序,而局部相对有序状态。

因此,当执行a = 1 and b = 2是a,b字段能用到索引的。而你执行a > 1 and b = 2时,a字段能用到索引,b字段用不到索引。因为a的值此时是一个范围,不是固定的,在这个范围内b值不是有序的,因此b字段用不上索引。

综上所示,最左匹配原则,在遇到范围查询的时候,就会停止匹配。

经典题型:

题型一:

如果sql为:

SELECT * FROM table WHERE a = 1 and b = 2 and c = 3;

如何建立索引?

正确回答:

  • (a,b,c)或者(c,b,a)或者(b,a,c)都可以,重点要的是将区分度高的字段放在前面,区分度低的字段放后面像性别、状态这种字段区分度就很低,我们一般放后面。
  • 假设区分度由大到小为b,a,c。那么我们就对(b,a,c)建立索引。如果我们的搜索条件中的列和索引列一致的话,这种情况就称为全值匹配,用到索引,与顺序无关,在执行sql的时候,查询优化器会自动帮我们优化查询顺序,让我们用上索引。

题型二:

如果sql为:

SELECT * FROM table WHERE a > 1 and b = 2;

如何建立索引?

正确回答:

  • 对(b,a)建立索引。如果你建立的是(a,b)索引,那么只有a字段能用得上索引,毕竟最左匹配原则遇到范围查询就停止匹配。
  • 如果对(b,a)建立索引那么两个字段都能用上,查询优化器会帮我们调整where后a,b的顺序,让我们用上索引。

题型三:

如果sql为:

SELECT * FROM `table` WHERE a > 1 and b = 2 and c > 3;

如何建立索引?

正确回答:

  • 对(b,a)或者(b,c)都可以,要结合具体情况具体分析(如字段的区分度)。

题型四:

如果sql为:

SELECT * FROM `table` WHERE a = 1 ORDER BY b;

如何建立索引?

正确回答:

  • 对(a,b)建索引,当a = 1的时候,b相对有序,可以避免再次排序!
  • 分析:一条SQL实际上可以分为三步
  • 第一步:根据where条件和统计信息生成执行计划,得到数据;
  • 第二步:将得到的数据排序,当执行处理数据(order by)时,数据库会先查看第一步的执行计划,看order by 的字段是否在执行计划中利用了索引。如果是,则可以利用索引顺序而直接取得已经排好序的数据。如果不是,则排序操作。
  • 第三步:返回排序后的数据

题型五:

如果sql为:

SELECT * FROM `table` WHERE a > 1 ORDER BY b;

如何建立索引?

正确回答:

  • 对(a)建立索引,因为a的值是一个范围,这个范围内b值是无序的,没有必要对(a,b)建立索引

题型六:

如果sql为:

SELECT * FROM `table` WHERE a = 1 AND b > 3 ORDER BY c;

如何建立索引?

正确回答:

  • 对(a,b)建立索引。
  • 分析:
  • 在where和order by出现索引设计冲突时,一般都是让where条件去使用索引来快速筛选出来一部分指定的数据,接着再进行排序;
  • 因为大多数情况基于索引进行where筛选可以最快速度筛选出想要的少部分数据,然后做排序的成本可能会小很多。

拓展:

MySQL支持两种方式的排序Using index排序Using filesort排序

  • Using index排序指MySQL扫描索引本身完成排序索引,可以保证数据的有序性,因此不需要再进行排序;
  • Using filesort排序:指文件排序,一般在内存中进行排序,占用CPU较多。如果待排结果较大,会产生临时文件I/O到磁盘进行排序,效率较低。

ORDER BY满足两种情况会使用Using index排序

  • order by语句使用索引最左前缀
  • 使用where子句与order by子句条件列组合满足索引最左前缀

17、讲一讲前缀索引?


当要索引的字段很长时,索引就会变得会变大变慢,如果只把很长字段的前面的公共部分作为一个索引,就会节约索引空间,提高索引效率。

注意:使用前缀索引系统就会忽略覆盖索引对查询性能的优化了。

场景:存储身份证

  • 直接创建完整索引,这样可能比较占用空间;
  • 创建前缀索引,节省空间,但会增加查询扫描次数,并且不能使用覆盖索引;
  • 倒序存储,再创建前缀索引,用于绕过字符串本身前缀的区分度不够的问题(前 6 位相同的很多);
  • 创建 hash 字段索引,查询性能稳定,有额外的存储和计算消耗,跟第三种方式一样,都不支持范围扫描。


18、了解索引下推优化不?


索引条件下推优化是 MySQL5.6 添加,可以在索引遍历过程中,对索引中包含的字段先做判断,直接过滤掉不满足条件的记录,减少回表次数

索引下推充分利用了索引中的数据,在查询出整行数据之前过滤掉无效的数据,再去主键索引树上查找。

举个例子

用户表 user,(name, age) 是联合索引:


SELECT * FROM user WHERE name LIKE '张%' AND age = 10; -- 头部模糊匹配会造成索引失效


  • 优化前:在非主键索引树上找到满足第一个条件的行,然后通过叶子节点记录的主键值再回到主键索引树上查找到对应的行数据,再对比 AND 后的条件是否符合,符合返回数据,需要 4 次回表。

  • 优化后:检查索引中存储的列信息是否符合索引条件,然后交由存储引擎用剩余的判断条件判断此行数据是否符合要求,不满足条件的不去读取表中的数据,满足下推条件的就根据主键值进行回表查询,2 次回表。


19、普通索引和唯一索引怎样选?


  1. 查询比较
  • 查询会以页为单位将数据页加载进内存,不需要一条记录一条记录读取磁盘。然后唯一索引根据条件查询到记录时就返回结果普通索引查到第一条记录往后遍历直到不满足条件由于都在内存中,不需要磁盘读取那么大开销,带来的额外查询开销忽略不计所以查询性能几乎一致
  1. 更新比较
  • 唯一索引由于更新时要检查唯一性,所以需要将数据页先加载进内存才能判断,此时直接操作内存,不需要操作change buffer。
  • 普通索引若数据在内存中直接内存中更新,否则会将更新操作先记录到change buffer中,等下一次查询将数据读到内存中,再进行change buffer里相关更新操作后将数据返回(也就是将更新索引页推迟到了查询的时候),这样一来,再写多读少的情况下就减少了磁盘lO,若写完就马上查询,就不必用change buffer,不但没提高多少效率还造成维护change buffer额外消耗。
  • change buffer 只限于用在普通索引的场景下,而不适用于唯一索引。
  1. 适合场景
  • 写多读少,选用普通索引更好,可以利用change buffer进行性能优化减少磁盘lO,将更新操作记录到change bufer,等查询来了将数据读到内存再进行修改.
  1. 总结
  • 由于唯一索引用不上 change buffer 的优化机制,因此如果业务可以接受,从性能角度出发 建议优先考虑普通索引。


20、如何选择索引列的顺序?


建立索引的目的是:希望通过索引进行数据查找,减少随机 IO,增加查询性能 ,索引能过滤出越少的数据,则从磁盘中读入的数据也就越少。

  • 区分度最高的放在联合索引的最左侧(区分度=列中不同值的数量/列的总行数)
  • 尽量把字段长度小的列放在联合索引的最左侧(因为字段长度越小,一页能存储的数据量越大,IO 性能也就越好)
  • 使用最频繁的列放到联合索引的左侧(这样可以比较少的建立一些索引)

21、覆盖索引是什么?


覆盖索引

  • 包含了所有查询字段 (where,select,order by,group by 包含的字段) 的索引。
  • 通过索引值可以直接找到要查询字段的值,而不需要通过主键值回表查询。

优点

  • 避免 Innodb 表进行索引的二次查询:  Innodb 是以聚集索引的顺序来存储的,对于 Innodb 来说,非聚簇索引在叶子节点中所保存的是行的主键信息,如果是用非聚簇索引查询数据的话,在查找到相应的键值后,还要通过主键进行二次查询才能获取我们真实所需要的数据。而在覆盖索引中,非聚簇索引的键值中可以获取所有的数据,避免了对主键的二次查询 ,减少了 IO 操作,提升了查询效率。
  • 可以把随机 IO 变成顺序 IO 加快查询效率:  由于覆盖索引是按键值的顺序存储的,对于 IO 密集型的范围查找来说,对比随机从磁盘读取每一行的数据 IO 要少的多,因此利用覆盖索引在访问时也可以把磁盘的随机读取的 IO 转变成索引查找的顺序 IO。

22、百万级以上的数据如何删除?


关于索引

由于索引需要额外的维护成本,因为索引文件是单独存在的文件,所以当我们对数据的增加,修改,删除,都会产生额外的对索引文件的操作,这些操作需要消耗额外的IO,会降低增/改/删的执行效率。

  1. 所以我们想要删除百万数据的时候可以先删除索引
  2. 然后删除其中无用数据
  3. 删除完成后重新创建索引创建索引也非常快

23、索引区分度?

索引区分度:

  • 索引的区分度等于列中不同值的数量/列的总行数表示字段不重复的比例 MySQL的索引都是排好序的,索引区分度越高,则排序越快,区分度越低,则排序越慢。

索引性能分析:

  • 对于选择性不高的列甚至可以不创建索引。如果选择性不高,极端性情况下可能会扫描全部或者大多数索引,然后再回表,这样反而增加了IO的消耗,这个过程可能不如直接走主键索引性能高。
  • 唯一键的区分度是1,而对于一些状态值,性别等字段区分度往往比较低,在数据量比较大的情况下,甚至有无限接近0。
  • 于索引也是需要占用内存的,所以在内存较为有限的环境下或者为了提高性能的情况下,区分度不高的索引几乎没有意义。

索引查看命令:

-- 选择性查看索引区分度
select count(DISTINCT column_name) / COUNT(*) from table_name; 
-- 查看索引区分度,我们关注Cardinality(基数)列 
SHOW INDEX FROM table_name;


相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
6月前
|
存储 SQL 关系型数据库
从0开始回顾MySQL---系列八
分库分表 1、为什么要分库分表? 1. 数据库中的数据量不一定是可控的,随着时间和业务的发展,库中的表会越来越多,表中的数据量也会越来越大,相应地数据操作,例如 增删改查的开销 也会越来越大;另外,若不进行分布式部署,而一台服务器的 资源 (CPU、磁盘、内存、IO 等)是有限的,最终数据库所能承载的数据量、数据处理能力都将遭遇瓶颈。 2. 所以,从 性能 和 可用性 角度考虑,会进行数据库拆分处理,具体地说,把原本存储于一个库的数据分块存储到多个库上,把原本存储于一个表的数据分块存储到多个表上,即 分库分表。 2、分库分表的具体实施策略 分库分表有 垂直切分 和 水平切分 两种方式,在
|
6月前
|
存储 关系型数据库 MySQL
从0开始回顾MySQL---系列三
索引 1、没有索引如何查找数据? 在一个页中的查找,分为两种情况: 以主键为搜索条件 可以在 页目录 中使用二分法快速定位到对应的槽,然后再遍历该槽对应 分组中的记录即可快速找到指定的记录。 以其他列作为搜索条件 对非主键列的查找的过程可就不这么幸运了,因为在数据页中并没有对非主键列建立所谓的 页目录 ,所以 我们无法通过二分法快速定位相应的 槽 。这种情况下只能从 最小记录 开始依次遍历单链表中的每条记录, 然后对比每条记录是不是符合搜索条件。很显然,这种查找的效率是非常低的。 在很多页中的查找,可以分为两个步骤: 定位到记录所在的页。 从所在的页内中查找相应的记录。 在没有索引的情
|
6月前
|
SQL 存储 关系型数据库
Mysql的NULLIF
Mysql的NULLIF
61 1
|
6月前
|
存储 关系型数据库 MySQL
从0开始回顾MySQL---系列一
基础 1、数据库的三范式是什么? 数据库范式是设计数据库时,需要遵循的一些规范。各种范式是条件递增的联系,越高的范式数据库冗余越小。常用的数据库三大范式为: 1. 第一范式(1NF):每个列都不可以再拆分,强调的是列的原子性,即数据库表的每一列都是不可分割的原 子数据项。 2. 第二范式(2NF):在满足第一范式的基础上,非主属性完全依赖于主码(主关键字、主键),消除非主属性对主码的部分函数依赖。 3. 第三范式(3NF):在满足第二范式的基础上,表中的任何属性不依赖于其它非主属性,消除传递依赖。简而言之,非主键都直接依赖于主键,而不是通过其它的键来间接依赖于主键。 2、MySQL 支持哪
|
6月前
|
存储 缓存 关系型数据库
从0开始回顾MySQL---系列二
InnoDB记录结构 1、InnoDB行格式 ? ● 我们平时是以记录为单位来向表中插入数据的,这些记录在磁盘上的存放方式也被称为 行格式 或者 记录格式 。 ● 设计InnoDB 存储引擎的作者到现在为止设计了4种不同类型的 行格式 ,分别是 Compact 、Redundant 、Dynamic 和 Compressed 行格式。 2、COMPACT行格式 ? 一条完整的记录其实可以被分为 记录的额外信息 和 记录的真实数据 两大部分。 记录的额外信息 这部分信息是服务器为了描述这条记录而不得不额外添加的一些信息,这些额外信息分为3类,分别是 变长字段长度列表 、 NULL值列表 和
|
6月前
|
存储 关系型数据库 MySQL
从0开始回顾MySQL---系列六
11、什么是MVCC? MVCC 全称 Multi-Version Concurrency Control,即多版本并发控制,用来解决读写冲突的无锁并发控制,可以在发生读写请求冲突时不用加锁解决,这个读是指的快照读(也叫一致性读或一致性无锁读),而不是当前读: ● 快照读:实现基于 MVCC,因为是多版本并发,所以快照读读到的数据不一定是当前最新的数据,有可能是历史版本的数据; ● 当前读:读取数据库记录是当前最新的版本(产生幻读、不可重复读),可以对读取的数据进行加锁,防止其他事务修改数据,是悲观锁的一种操作,读写操作加共享锁或者排他锁和串行化事务的隔离级别都是当前读。 -- 简单的sel
|
6月前
|
存储 SQL 关系型数据库
从0开始回顾MySQL---系列五
事务 1、什么是数据库事务? 事务(Transaction)是访问和更新数据库的程序执行单元,是逻辑上的一组操作,要么都执行,要么都不执行。如果任意一个操作失败,那么整组操作即为失败,会回到操作前状态或者是上一个节点。 因此,事务是保持 逻辑数据一致性 和 可恢复性 的重要利器。而锁是实现事务的关键,可以保证事务的完整性和并发性。 事务控制语句: ● BEGIN 或 START TRANSACTION 显式地开启一个事务; ● COMMIT 也可以使用 COMMIT WORK,不过二者是等价的。COMMIT 会提交事务,并使已对数据库进行的所有修改成为永久性的; ● ROLLBAC
|
6月前
|
存储 关系型数据库 MySQL
从0开始回顾MySQL---系列七
锁 1、为什么要加锁? 1. 当多个用户并发地存取数据时,在数据库中就会产生多个事务同时存取同一数据的情况,若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数据库的一致性。 2. 因此加锁是为了在多用户环境下保证数据库完整性和一致性。 2、MySQL都有哪些锁呢? 锁的分类: ● 按操作分类: ○ 共享锁:也叫读锁。对同一份数据,多个事务读操作可以同时加锁而不互相影响 ,但不能修改数据 ○ 排他锁:也叫写锁。当前的操作没有完成前,会阻断其他操作的读取和写入 ● 按粒度分类: ○ 表级锁:会锁定整个表,开销小,加锁快;不会出现死锁;锁定力度大,发生锁冲突概率高,并
|
6月前
|
SQL 关系型数据库 MySQL
从0开始回顾MySQL---系列九
SQL优化 1、一条sql语句执行很慢的原因有哪些? ⚡ 一个SQL执行的很慢,我们要分两种情况讨论: 1. 大多数情况下很正常,偶尔很慢,则有如下原因: ● 数据库在刷新脏页(内存数据页跟磁盘数据页内容不一致的时候,我们称这个内存页为“脏页),例如redo log 写满了需要同步到磁盘。 ● 执行的时候,遇到锁,如表锁、行锁。 ● sql语句写的不好。 2. 这条SQL语句一直执行的很慢,则有如下原因: ● 没有用上索引或者索引失效:比如该字段没有索引,由于对字段进行运算、函数操作导致无法用索引。 ● 有索引可能会走全表扫描: ○ 怎样判断是否走全表扫描? ○ 某
|
存储 SQL JSON
MySQL学习---17、MySQL8其它新特性
MySQL学习---17、MySQL8其它新特性
下一篇
无影云桌面