Mysql选择不使用索引

时间:2017-08-23 13:03:31

标签: mysql indexing

我有一个大表(10M行),有3列:x,y,status。 我有一个关于x,y的主索引。

我要求' SELECT * FROM table where (x,y) in (select 1234,5678)大约需要5个小时 而请求SELECT * FROM table where (x,y) in (1234,5678)给出的结果小于0.01s

我认为它是索引的问题,我尝试添加force index但没有成功。

当我对两个查询运行解释时,第一个不使用索引:

EXPLAIN SELECT * FROM table where (x,y) in (select 1234,5678)

id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows     | filtered | Extra          |
+----+-------------+-------+------------+------+---------------+------+---------+------+----------+----------+----------------+
|  1 | PRIMARY     | table | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 10794773 |   100.00 | Using where    |
|  2 | SUBQUERY    | NULL  | NULL       | NULL | NULL          | NULL | NULL  | NULL |     NULL |     NULL | No tables used |

EXPLAIN SELECT * FROM table where (x,y) in (1234,5678)

| id | select_type | table | partitions | type  | possible_keys | key     | key_len | ref         | rows | filtered | Extra |
+----+-------------+-------+------------+-------+---------------+---------+---------+-------------+------+----------+-------+
|  1 | SIMPLE      | table | NULL       | const | PRIMARY       | PRIMARY | 8       | const,const |    1 |   100.00 | NULL  |
+----+-------------+-------+------------+-------+---------------+---------+---------+-------------+------+----------+-------+

我当然希望使用第一种语法,因为真正的查询就像UPDATE table set status=123 where (x,y) IN (SELECT x,y from table2 where ... );

我真的不会忽视这种行为

1 个答案:

答案 0 :(得分:0)

您不需要选择1234,5678子查询,而是使用...((1234,5678))(请注意值周围的双括号):

SELECT * FROM table where (x,y) in ((1234,5678))

如果使用in()运算符针对常量值列表检查多个字段,则需要将值集包括在括号中:

SELECT * FROM table where (x,y) in ((1,1),(2,3),...(n,m))

上述语法将使MySQL能够将x,y字段与常量值匹配,因此查询可以利用x,y字段上的多列索引。

但是,对于带有子查询的update查询,这可能无效。在这种情况下,我会用连接而不是子查询重写update

UPDATE table
    INNER JOIN table2 on table.x=table2.x and table.y=table2.y
    SET table.status=123
    WHERE table2.fieldname=...

如果x,y在两个表中都被编入索引,那么连接应该很快。此外,如果扩展table2索引以涵盖where条件,那么这样的查询可能非常快。