shi*_* xu 5 mysql composite-key query-performance
我有一张表: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
Run Code Online (Sandbox Code Playgroud)
现在我有一个 Sql:
select * from student_homework where student_id=100 and type=1结果explain如下:
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
Run Code Online (Sandbox Code Playgroud)
执行计划是uk_sid_lsnid_version。
我的问题是查询条件type在这里如何工作?数据库引擎是否扫描所有(缩小的)记录?根据我的理解,树形层次结构是:
student_id
/ \
lesson_id lesson_id
/ \
curriculum_version curriculum_version
/ \
type type
Run Code Online (Sandbox Code Playgroud)
对于查询条件(student_id, type),student_id匹配树索引的根。然而,如果type不匹配索引lesson_id,数据库引擎将应用于type所有已过滤的记录student_id。
student_id很大,查询成本仍然很昂贵。是的,你的理解是正确的,mysql将仅使用uk_sid_lsnid_version索引来匹配student_id,而过滤type将在匹配的行的减少集上进行student_id。
提示在extra解释结果栏:使用索引条件
\n\n使用索引条件(JSON 属性:using_index_condition)
\n
\n\n通过访问索引元组并首先测试它们来确定是否读取完整的表行来读取表。这样,索引信息用于推迟(\xe2\x80\x9cpush down\xe2\x80\x9d)读取完整表行,除非有必要。请参见第 8.2.1.6 节,\xe2\x80\x9c索引条件下推优化\xe2\x80\x9d。
\n
第 8.2.1.6 节,\xe2\x80\x9cIndex 条件下推优化将此技术的步骤描述为:
\n\n\n\n
\n- 获取下一行的索引元组(但不是完整的表行)。
\n- 测试适用于该表的 WHERE 条件部分,并且可以仅使用索引列进行检查。如果不满足条件,则继续查找下一行的索引元组。
\n- 如果满足条件,则使用索引元组定位并读取全表行。
\n- 测试适用于此表的 WHERE 条件的剩余部分。根据测试结果接受或拒绝该行。
\n
是不是在student_id,type上再加一个复合索引会更好是一个我们无法客观回答的问题,需要你去测试。
\n如果使用当前索引的查询速度很好,那么您可能不需要新索引。您还需要权衡有多少其他查询将使用该索引 - 仅为一个查询创建索引没有多大意义。您还需要权衡该type领域的选择性。具有有限值列表的类型字段通常选择性不够。MySQL 可能决定使用索引条件下推,因为 Student_id、类型索引不是覆盖索引,并且 mysql 无论如何都必须获取完整行。
| 归档时间: |
|
| 查看次数: |
458 次 |
| 最近记录: |