mysql:在where-in子句中使用复合键进行非常慢的查询

wz8daaqr  于 2021-06-18  发布在  Mysql
关注(0)|答案(1)|浏览(380)

我有一个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

w46czmvw

w46czmvw1#

“行构造函数”直到5.7.3才得到优化。例子 WHERE (id1, id2) = (11, 22) . 来自变更日志:2013-12-03 5.7.3
里程碑13——添加或更改的功能:
优化器现在可以将范围扫描访问方法应用于以下形式的查询:
选择。。。从t1开始,其中(列1,列2)在(('a','b'),('c','d'));
以前,要使用范围扫描,必须将查询编写为:
选择。。。从t1开始,其中(列1='a'和列2='b')或(列1='c'和列2='d');
要使优化器使用范围扫描,查询必须满足以下条件:
只能在 predicate 中使用,不能在中使用。
in predicate 左侧的行构造函数中可能只有列引用。
in predicate 的右侧必须有多个行构造函数。
in predicate 右侧的行构造函数只能包含运行时常量,这些常量可以是文本,也可以是在执行期间绑定到常量的本地列引用。
解释适用查询的输出将从完整表或索引扫描更改为范围扫描。通过检查handler\u read\u first、handler\u read\u key和handler\u read\u next状态变量的值,也可以看到更改。

相关问题