MySQL高级第九篇:覆盖索引和索引条件下推等相关策略

news/2024/11/24 12:57:51/

MySQL高级第九篇:覆盖索引和索引条件下推等相关策略

  • 一、覆盖索引
    • 1. 什么是覆盖索引?
    • 2. 覆盖索引的好处
      • 避免lnnodb表进行索引的二次查询(回表)
      • 可以把随机 IO 变成顺序 IO 加快查询效率
  • 二、索引条件下推
    • 1. 举例:
    • 2. ICP的使用条件
  • 三、其他相关策略
    • 1. EXISTS 和 IN的选择
    • 2. COUNT(*) ,COUNT(1) 和 COUNT(字段)
    • 3. 关于SELECT(*)
    • 4. 关于LIMIT 1
    • 5. 关于 COMMIT

一、覆盖索引

1. 什么是覆盖索引?

  • 解释一:

    • 索引是高效找到行的一个方法,但是一般数据库也能使用索引找到一个列的数据,因此它不必读取整个行。
    • 毕竟索引叶子节点存储了它们索引的数据,当能通过读取索引就可以得到想要的数据时,那就不需要读取行了。
      一个索引包含了满足查询结果的数据就叫做覆盖索引。
  • 解释二:

    • 非聚簇复合索引的一种形式,它包括在查询里的SELECT、JOIN和WHERE子句用到的所有列(即建索引的字段正好是覆盖查询条件中所涉及的字段)。
      简单说就是,索引列+主键包含SELECT到FROM之间查询的列。

举例:

# id为主键,创建一个age,NAME联合索引
CREATE INDEX idx_age_name ON student (age,NAME);# 前边我们学习过,不等于会使索引失效,但是下边会打破这个规则,因为优化器根据执行成本选择到底使不使用# 这条语句就用不到索引,因为 SELECT * ,反之会回表操作,就没有必要使用索引了
EXPLAIN SELECT * FROM student WHERE age <> 20;# 这条就可以,因为查询的字段刚好就是索引字段,不需要回表
EXPLAIN SELECT age,NAME FROM student WHERE age <> 20;

2. 覆盖索引的好处

避免lnnodb表进行索引的二次查询(回表)

  • lnnodb是以聚集索引的顺序来存储的,对于lnnodb来说,二级索引在叶子节点中所保存的是行的主键信息,如果是用二级索引查询数据,在查找到相应的键值后,还需通过主键进行二次查询才能获取我们真实所需要的数据。
  • 在覆盖索引中,二级索引的键值中可以获取所要的数据,避免了对主键的二次查询,减少了IO操作,提升了查询效率。

可以把随机 IO 变成顺序 IO 加快查询效率

  • 由于覆盖索引是按键值的顺序存储的,对于IO密集型的范围查找来说,比随机从磁盘读取每一行的数据IO要少的多,因此利用覆盖索引在访问时也可以把磁盘的随机读取的IO转变成索引查找的顺序IO。

由于覆盖索引可以减少树的搜索次数,显著提升查询性能,所以使用覆盖索引是一个常用的性能优化手段。

二、索引条件下推

1. 举例:

# key1是索引,如下查询
EXPLAIN SELECT * FROM s1 WHERE key1 > 'z' AND key1 LIKE '%a';
  • 按照我们之前的学习,like以通配符%开头索引失效,应该是先用索引查询条件 key1 > ‘z’,然后进行回表,在查到的记录中在查找条件 key1 LIKE ‘%a’
  • 其实并不是的,优化器会 先用索引查询条件 key1 > 'z',不回表,继续在这些索引中过滤条件 key1 LIKE '%a',最后只回表一次,这就是索引条件下推。

ICP 默认是开启的,可以选择手动关闭

2. ICP的使用条件

  • 如果表访问的类型为range、ref、eq_ref 和 ref_or_null 可以使用ICP
  • ICP可以用于 InnoDB 和 MyISAM 表,包括分区表 InnoDB 和 MyISAM 表
  • 对于InnoDB表,ICP仅用于二级索引。ICP的目标是减少全行读取次数,从而减少I/O操作。
  • 当SQL使用覆盖索引时,不支持ICP。因为这种情况下使用ICP不会减少 I/O。
  • 相关子查询的条件不能使用ICP。

三、其他相关策略

1. EXISTS 和 IN的选择

# 
SELECT * FROM A WHERE cc INSELECT cc FROM B)SELECT * FROM A WHERE EXISTS(SELECT cc FROM B WHERE B.cc=A.cc)
  • 当 A 小于 B 时,使用 EXISTS,因为 EXISTS 执行相当于一个嵌套循环,每次拿 A 的一条数据,去 B 里边循环比较。
  • 当 B小于 A 时,使用 IN,因为 B 表较小,IN先计算出 IN 中语句的结果,然后外层直接精确匹配。

总结就是:小表驱动大表

2. COUNT(*) ,COUNT(1) 和 COUNT(字段)

  • COUNT(*) 和 COUNT(1)
    • 这两本质上没有什么区别,执行效率相差不多。
    • 如果是在 MyISAM 中,统计表行数只需要O(1)复杂度,因为每张 MyISAM 表都有一个 meta 存储了row_count。
    • 如果是InnoDB,需要全表扫描,因为 它支持事物,采用行级锁和MVCC机制,无法维护row_count,时间复杂度是O(n)。
  • COUNT(字段)
    • 在 InnoDB 中,要尽量采用二级索引,因为聚簇索引包含信息较多。
    • 对于COUNT(*) 和 COUNT(1),其实系统会自动选择较小的二级索引来统计。

3. 关于SELECT(*)

  • 不建议使用:
    • MySQL在解析的过程中,会通过查询数据字典将 “ * ” 按序转换成所有列名,这会大大的耗费资源和时间。
    • 无法使用覆盖索引。

4. 关于LIMIT 1

  • 针对的是会扫描全表的SQL语句,如果你可以确定结果集只有一条,那么加上 LIMIT 1 的时候,当找到一条结果的时候就不会继续扫描了,这样会加快查询速度。
  • 如果数据表已经对字段建立了唯一索引,那么可以通过索引进行查询,不会全表扫描的话,就不需要加上LIMIT 1了。

5. 关于 COMMIT

  • 只要有可能,在程序中尽量多使用COMMIT,这样程序的性能会得到提高,需求也会因为COMMIT所释放的资源而减少。

http://www.ppmy.cn/news/36684.html

相关文章

Parasoft帮助中移智行顺利获得A-SPICE L3和ISO26262功能安全认证证书

2023年2月24日&#xff0c;国际独立第三方检测、检验和认证机构德国莱茵TV集团为中移智行网络科技有限公司&#xff08;以下简称“中移智行”&#xff09;颁布了A-SPICE L3和ISO26262功能安全产品ASIL B认证证书&#xff0c;标志着中移智行在软件质量体系管理和产品技术方面走在…

CE4003S2B1对循环流化床锅炉的调节

​CE4003S2B1对循环流化床锅炉的调节 循环流化床作为一种清洁高效燃烧技术在国际上被广泛认可&#xff0c;具有燃烧适应性广、燃烧效率高、氮氧化合物排量低、负荷调节范围大、污染物排放低等特点&#xff0c;属于环保型锅炉&#xff0c;是国家大力推广的新型锅炉。燃烧工艺如图…

rdma struct ibv_qp_attr属性timeout,retry_cnt,rnr_retry等字段含义。

如下&#xff1a; struct ibv_qp_attr {//...uint8_t timeout;uint8_t retry_cnt;uint8_t rnr_retry;//... };一&#xff1a;timeout字段 timeout表示等待ACK或NACK的无限时间。 这意味着如果消息中的任何包丢失&#xff0c;并且没有发送ACK或NACK&#xff0c;则不会发生…

VUE强制刷新渲染DOM

开始是 将获取到的数据给到 this.$api.coreStock.GetStockID({ id: data }).then((res) > { document.getElementById("mainconbarcode").value res.data.boxCode; }); 但后面影响数据保存 就想直接给到 dataForm.mainconbarcode res.data&#xff1b; this.…

C++ 98/03 应该学习哪些知识14

重载、重写和覆盖 C中的重载&#xff08;overloading&#xff09;、重写&#xff08;override&#xff09;和覆盖&#xff08;overriding&#xff09;是三个重要的概念&#xff0c;它们在C语言中都有着不同的意义和用法。在本文中&#xff0c;我们将详细解释这三个概念的含义&…

【基础算法】哈希表

系列综述&#xff1a; &#x1f49e;目的&#xff1a;本系列是个人整理为了秋招算法的&#xff0c;整理期间苛求每个知识点&#xff0c;平衡理解简易度与深入程度。 &#x1f970;来源&#xff1a;材料主要源于代码随想录进行的&#xff0c;每个算法代码参考leetcode高赞回答和…

Spring Boot Aop初接触

AOP&#xff08;面向切面编程&#xff09;&#xff0c;或多或少都听过一点。名字比较怪&#xff0c;切面&#xff0c;不容易理解&#xff0c;但其中真正含义&#xff0c;无非就是旁路控制&#xff0c;非侵入式编码之类。比如我想加个操作日志功能&#xff0c;利用AOP&#xff0…

Java实现一个简单的东南西北中的面板

目录 一、前言 二、代码部分 1.代码 三、程序运行结果&#xff08;面板弹出&#xff09; 四、涉及到的知识点代码 一、前言 1.本代码是我在上学时写的&#xff0c;有一些地方没能完美实现&#xff0c;请包涵也请多赐教&#xff01; 2.本弹窗界面可以根据简单的要求进行…