MySQL含WHERE IN的排序查询仍使用filesort而非索引问题咨询
WHERE IN多值导致分段有序无法全局合并
当WHERE IN包含多个不同的user_id时,InnoDB会在索引里分别定位每个user_id对应的date和planing_hour_id有序数据,但这些来自不同user_id的结果片段本身是无序的。MySQL没法直接把这些分段有序的数据拼成全局有序的结果集,只能先取出所有符合条件的数据,再做filesort来完成整体排序。排序逻辑和索引顺序不匹配
检查你的ORDER BY子句是否严格贴合复合索引的字段顺序和排序方向。比如索引是date ASC, planing_hour_id ASC,但你排序用的是ORDER BY date DESC, planing_hour_id ASC,或者排序字段包含索引外的列,这种情况下MySQL没法利用索引的有序性,只能触发filesort。索引覆盖不全需要回表
如果查询的SELECT列表包含了my_perfect_index之外的字段,InnoDB得先通过索引找到主键,再回表去拿额外字段(也就是书签查找)。这种场景下,MySQL可能觉得直接扫表再加filesort的成本更低,就放弃了索引排序。优化器成本估算倾向于filesort
MySQL优化器会根据数据量、索引基数等统计信息算成本。如果WHERE IN匹配的行数占表总行数比例太高(比如超过30%),优化器会判断全表扫描+filesort比用索引更划算,所以选了filesort。可以跑ANALYZE TABLE更新表统计信息,让优化器判断更准确。隐式类型转换破坏索引有效性
如果user_id是整数类型,但你在WHERE IN里传了字符串类型的值(比如WHERE user_id IN ('1','2')),会触发隐式类型转换,导致索引没法被有效使用,进而引发filesort。
内容的提问来源于stack exchange,提问作者Fusion

