mysql - 优化 MySQL 查询 : long list of IN vs narrowing down search first

标签 mysql sql select optimization

在对 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/

相关文章:

MySQL - 一行中具有相同时间戳的所有条目

mysql - 将值添加到字段中

sql - SSMS 2012 : Convert DATETIME to Excel serial number

SQL UPDATE SELECT 与 WHERE

sql - 批量postgres多个JDBC select语句

sql - 将具有不同行类型的多个查询显示为一个结果

mysql - 构建模式时无法添加外键约束 SQL

sql - 从 Presto 中的行数组中提取

ios - 如何按日期查询 'task'条记录

php - 使用 PDO 插入记录后获取 mysql 最后插入 ID