如何使Mysql使用索引在'where'中具有一元条件的选择

时间:2018-10-29 00:53:48

标签: mysql

我在Ruby on Rails应用程序中查询了一个奇怪的一元条件,其中:

SELECT * FROM messages WHERE (active)  ORDER BY id DESC;

我什至不知道允许这样的条件,并且在任何地方都找不到描述此语法的文档。实验表明,这等同于

SELECT * FROM messages WHERE active!=0  ORDER BY id DESC;

问题是Mysql仅将索引用于第二个变量:

mysql> explain SELECT * FROM messages WHERE (active)  ORDER BY id DESC;
+----+-------------+----------+------+---------------+------+---------+------+--------+-----------------------------+
| id | select_type | table    | type | possible_keys | key  | key_len | ref  | rows   | Extra                       |
+----+-------------+----------+------+---------------+------+---------+------+--------+-----------------------------+
|  1 | SIMPLE      | messages | ALL  | NULL          | NULL | NULL    | NULL | 560646 | Using where; Using filesort |
+----+-------------+----------+------+---------------+------+---------+------+--------+-----------------------------+


mysql> explain SELECT * FROM messages WHERE active!=0  ORDER BY id DESC;
+----+-------------+----------+-------+------------------+--------+---------+------+------+---------------------------------------+
| id | select_type | table    | type  | possible_keys    | key    | key_len | ref  | rows | Extra                                 |
+----+-------------+----------+-------+------------------+--------+---------+------+------+---------------------------------------+
|  1 | SIMPLE      | messages | range | active_id,active | active | 2       | NULL | 1394 | Using index condition; Using filesort |
+----+-------------+----------+-------+------------------+--------+---------+------+------+---------------------------------------+

我无法更改查询文本,因为正如我所解释的那样,该应用程序会即时生成查询,并且它们不会存储在任何地方。所以我的问题是:

  1. 我是否正确理解此一元子句的含义?
  2. 为什么这样的查询不使用索引?
  3. 是否可以使Mysql在此索引上使用索引而不更改查询文本?

1 个答案:

答案 0 :(得分:0)

  1. 是的,两个子句应该具有相同的结果(假定为int类型)。

  2. 服务器代码似乎无法识别等效项。存在于MySQL-8.0上的测试和相同的查询计划。 MariaDB-10.2和10.3在这两种情况下似乎都使用索引。

  3. 否。

如果active中的值范围是0或1;如果SELECT * FROM messages WHERE active=1 ORDER BY id DESC是主键,则filesort查询将能够使用索引进行排序(因此没有id);