在对 IN 的大列表进行 SELECT 时,先缩小搜索范围会更快吗?
假设:
- id 是主键
- 表有 200 万行
- @list_of_id 中的 ID 总是靠得很近,但不是连续的(选择在同一个月左右创建的一组人的子集)
当@list_of_id 为 1K、10K 或 100K 时,以下查询应如何执行?
查询 1:
SELECT * FROM people
WHERE id IN (@list_of_id);
查询 2a(首先缩小搜索范围):
SELECT * FROM people
WHERE id <= @max_id
AND id >= @min_id
AND id IN (@list_of_id);
查询 2b(可能较慢):
SELECT * FROM people
WHERE MONTH(created) = @month
AND id IN (@list_of_id);
最佳答案
MySQL 5.6 引入了一些优化器改进,专门针对 IN()
谓词中的长 ID 列表。阅读https://dev.mysql.com/doc/refman/5.6/en/range-optimization.html#equality-range-optimization
如果您依赖索引进行 IN()
搜索,那么该优化是相关的。如果您像在查询 2a 中那样首先缩小搜索范围,索引将用于不等式表达式,但不用于 IN()
谓词。
一般而言,当您有多个搜索词时,只有一个范围谓词会使用索引进行优化。范围谓词是 =
以外的任何内容。
因此在您的 2a 示例中,BETWEEN
谓词将使用索引(我相信您使用的一对不等式表达式将被优化,就好像它是一个 BETWEEN
谓词一样), 然后 IN()
谓词将只线性搜索第一次索引扫描的结果。
在您的 2b 示例中,尝试使用 MONTH(created)
缩小搜索范围根本不能使用索引。想想在电话簿中查找人——如果我要你找到每个中间首字母是“J”的人。那么电话簿按姓氏排序的事实对您没有帮助。
您可能想查看我的演示文稿 How to Design Indexes, Really ,或视频:https://www.youtube.com/watch?v=ELR7-RdU9XU
关于mysql - 优化 MySQL 查询 : long list of IN vs narrowing down search first,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45885265/