MySql复合索引是否为此SQL命中?

问题描述

我有一张表:student_homework,它的综合索引之一是uk_sid_lsnid_version(student_id,lesson_id,curriculum_version,type)

student_homework    0   uk_sid_lsnid_version    1   student_id  A   100             BTREE       
student_homework    0   uk_sid_lsnid_version    2   lesson_id   A   100             BTREE       
student_homework    0   uk_sid_lsnid_version    3   curriculum_version  A   100             BTREE       
student_homework    0   uk_sid_lsnid_version    4   type    A   100             BTREE   

现在我有一个sqlselect * from student_homework where student_id=100 and type=1explain的结果是:

1   SIMPLE  student_homework        ref uk_sid_lsnid_version,idx_student_id_update_time uk_sid_lsnid_version    4   const   20  10.0    Using index condition

执行计划为 uk_sid_lsnid_version

对我来说,问题是查询条件type在这里如何工作?数据库引擎是否扫描所有(缩小的)记录?以我的理解,树的层次结构是:

              student_id 
               /       \
           lesson_id     lesson_id
            /                      \  
     curriculum_version          curriculum_version
       /            \
      type         type

对于查询条件(student_id,类型)student_id与树索引的根匹配。但是,type与索引lesson_id不匹配,数据库引擎会将type应用于已被student_id过滤的所有记录

  1. 我的理解正确吗?如果带有student_id的子集记录很大,则查询成本仍然很高。
  2. 查询条件 student_id = 100和类型= 0 type = 0和Student_id = 100
  3. 之间没有区别
  4. 要充分利用复合索引,如果添加新的复合索引(student_id,type)会更好吗?

解决方法

是的,您的理解是正确的,mysql将仅使用uk_sid_lsnid_version索引来匹配student_id,而对type的过滤将在与之匹配的精简行集合上进行。 student_id

提示位于解释结果的extra列中:Using index condition

使用索引条件(JSON属性:using_index_condition)

通过访问索引元组并首先对其进行测试以确定是否读取完整的表行来读取表。这样,除非有必要,否则索引信息将用于延迟(“下推”)读取整个表行。请参见第8.2.1.6节“索引条件下推优化”。

Section 8.2.1.6,“Index Condition Pushdown Optimization将这种技术的步骤描述为:

  1. 获取下一行的索引元组(而不是整个表行)。
  2. 测试适用于此表的WHERE条件部分,仅可使用索引列进行检查。如果条件不是 如果满意,请转到下一行的索引元组。
  3. 如果满足条件,则使用索引元组来定位并读取整个表行。
  4. 测试适用于此表的WHERE条件的其余部分。根据测试结果接受或拒绝该行。

在student_id上添加另一个复合索引是否更好,类型是我们无法客观回答的问题,您需要对其进行测试。

如果使用当前索引进行查询的速度很好,那么您可能不需要新索引。您还需要权衡使用该索引的其他查询的数量-仅为一个查询创建索引没有多大意义。您还需要权衡type字段的选择性。值列表有限的类型字段通常不够选择性。由于student_id,类型index不是覆盖索引,因此mysql可能决定使用索引条件下推式,而mysql仍然必须获得完整的行。