[英]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_first 、 Handler_read_key和Handler_read_next状态变量的值也可以看到更改。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.