繁体   English   中英

MySQL:在 WHERE IN 子句中使用复合键的查询非常慢

[英]MySQL: very slow query using composite key in WHERE IN clause

我有一个带有复合主键的 MySQL 表:(id1, id2)。 我想获取 (id1, id2) 在对列表中的所有行,例如 ((1,2), (2,6), (1,6))。 当这个对列表只包含一个元素时,索引似乎被使用,因为查询非常快。 当对列表包含多个元素时,查询速度极慢:

mysql> SELECT id1, id2 FROM my_table WHERE (id1, id2) in ((1817279, 0));
+---------+--------+
|   id1   |   id2  |
+---------+--------+
| 1817279 |      0 |
+---------+--------+
1 row in set (0.00 sec)

mysql> SELECT id1, id2 FROM my_table WHERE (id1, id2) in ((1819781, 2));
+---------+--------+
|   id1   |   id2  |
+---------+--------+
| 1819781 |      2 |
+---------+--------+
1 row in set (0.00 sec)

mysql> SELECT id1, id2 FROM my_table WHERE (id1, id2) in ((1817279, 0), (1819781, 2));
+---------+--------+
|   id1   |   id2  |
+---------+--------+
| 1817279 |      0 |
| 1819781 |      2 |
+---------+--------+
2 rows in set (1 min 22.72 sec)

我尝试使用FORCE INDEX (PRIMARY)没有成功。 知道为什么 MySQL 无法使用索引吗?

这是我的 MySQL 版本: mysql Ver 14.14 Distrib 5.6.33, for debian-linux-gnu (x86_64) using EditLine wrapper

“行构造函数”直到 5.7.3 才被优化。 示例WHERE (id1, id2) = (11, 22) 来自更新日志:2013-12-03 5.7.3

里程碑 13 -- 添加或更改的功能:

优化器现在可以将范围扫描访问方法应用于这种形式的查询:

SELECT ... FROM t1 WHERE (col_1, col_2) IN (('a', 'b'), ('c', 'd'));

以前,要使用范围扫描,必须将查询编写为:

SELECT ... FROM t1 WHERE ( col_1 = 'a' AND col_2 = 'b' ) OR ( col_1 = 'c' AND col_2 = 'd' );

要使优化器使用范围扫描,查询必须满足以下条件:

  • 只能使用 IN 谓词,不能使用 NOT IN。

  • 在 IN 谓词左侧的行构造函数中可能只有列引用。

  • IN 谓词的右侧必须有多个行构造函数。

  • IN 谓词右侧的行构造函数必须仅包含运行时常量,即在执行期间绑定到常量的文字或本地列引用。

适用查询的 EXPLAIN 输出将从全表或索引扫描更改为范围扫描。 通过检查Handler_read_firstHandler_read_keyHandler_read_next状态变量的值也可以看到更改。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM