Mysql 查询未使用我在多个列上的索引

Mysql 查询未使用我在多个列上的索引,mysql,Mysql,我正在尝试优化此查询: select id, entity_type from tv_classified where entity_type != 2 and state = 0 and dateExpiration < now(); 54630 rows in set (1 min 0.42 sec) 问题是我的查询仍然占用相同的时间,忽略索引: explain select id, entity_type from tv_classified where enti

我正在尝试优化此查询:

select id, entity_type
from tv_classified
where entity_type != 2
    and state = 0
    and dateExpiration < now();

54630 rows in set (1 min 0.42 sec)
问题是我的查询仍然占用相同的时间,忽略索引:

explain select id, entity_type from tv_classified where entity_type != 2 and state = 0 and dateExpiration < now();
+----+-------------+---------------+------+------------------------------------------------------------------+-----------+---------+-------+---------+-------------+
| id | select_type | table         | type | possible_keys                                                    | key       | key_len | ref   | rows    | Extra       |
+----+-------------+---------------+------+------------------------------------------------------------------+-----------+---------+-------+---------+-------------+
|  1 | SIMPLE      | tv_classified | ref  | dateExpiration_idx,entity_type_idx,state_idx,full_expiration_idx | state_idx | 2       | const | 1483498 | Using where |
+----+-------------+---------------+------+------------------------------------------------------------------+-----------+---------+-------+---------+-------------+
explain从分类为实体类型的tv中选择id、实体类型!=2和state=0,dateExpiration
Mysql似乎不使用这个索引,而是更喜欢使用“state”字段上的索引

我知道我可以在查询中使用
use index(full\u expiration\u idx)
(它工作速度很快,1分钟->0.5秒),但我想了解为什么Mysql不单独使用他


关于,

您已经创建了一个复合键,该键可用于连接条件,其中您的3列与另一个表的3列连接。因为您在这里使用的是筛选条件,所以请为3列创建3个单独的索引。

您已经创建了一个复合键,可以在3列与另一个表的3列联接的联接条件下使用该键。因为您在这里使用的是过滤条件,所以为3列创建3个单独的索引。

对于条件链来说,复合索引通常很好,但在这里(我认为这是因为第一个条件是
!=
,而不是
=
),OP必须依赖索引合并优化,这确实需要单独的单列索引。我正在阅读并试图刷新我的记忆。免责声明:我不知道IMO会有帮助。复合索引通常对条件链很有用,但在这里(我认为这是因为第一个条件是
!=
,而不是
=
),OP必须依赖于索引合并优化,它确实需要单独的单列索引。我正在阅读并试图刷新我的记忆。免责声明:我不知道IMO会有帮助。我不知道,但我对
有直觉=。如果您尝试使用
entity_type=2
,您能否告诉我们(出于兴趣)是否使用了索引?我意识到这不是你想做的,但这可能证实了我的想法。@LightnessRacesinOrbit好的呼叫,如果我更改
,就会选择好的索引2
在(0,1,3,4)
中有
,你知道为什么吗?我想这是因为你在键的最左边没有一个“已知范围”。如果您想象一下索引数据本身是如何构造的,MySQL不能简单地在
实体类型
上进行查找,然后在
状态下进行查找,最后在该状态下进行范围查找。它可以使用
=
,但是使用您的
=
它必须查看
实体类型
树的几乎每一个叶子(实际上,除了一个之外,它们几乎都是),因此索引查找的好处并不真正存在。它决定没有它会更好。但是,大量的免责声明,我几乎不知道我在这里说的是什么。(我也没有一个解决方案给你!)我很想看看DBA对此有什么看法。你能给我们展示一下从tv_classified procedure analysis()中选择*的输出吗;我不知道,但我对
有直觉=。如果您尝试使用
entity_type=2
,您能否告诉我们(出于兴趣)是否使用了索引?我意识到这不是你想做的,但这可能证实了我的想法。@LightnessRacesinOrbit好的呼叫,如果我更改
,就会选择好的索引2
在(0,1,3,4)
中有
,你知道为什么吗?我想这是因为你在键的最左边没有一个“已知范围”。如果您想象一下索引数据本身是如何构造的,MySQL不能简单地在
实体类型
上进行查找,然后在
状态下进行查找,最后在该状态下进行范围查找。它可以使用
=
,但是使用您的
=
它必须查看
实体类型
树的几乎每一个叶子(实际上,除了一个之外,它们几乎都是),因此索引查找的好处并不真正存在。它决定没有它会更好。但是,大量的免责声明,我几乎不知道我在这里说的是什么。(我也没有一个解决方案给你!)我很想看看DBA对此有什么看法。你能给我们展示一下从tv_classified procedure analysis()中选择*的输出吗;
explain select id, entity_type from tv_classified where entity_type != 2 and state = 0 and dateExpiration < now();
+----+-------------+---------------+------+------------------------------------------------------------------+-----------+---------+-------+---------+-------------+
| id | select_type | table         | type | possible_keys                                                    | key       | key_len | ref   | rows    | Extra       |
+----+-------------+---------------+------+------------------------------------------------------------------+-----------+---------+-------+---------+-------------+
|  1 | SIMPLE      | tv_classified | ref  | dateExpiration_idx,entity_type_idx,state_idx,full_expiration_idx | state_idx | 2       | const | 1483498 | Using where |
+----+-------------+---------------+------+------------------------------------------------------------------+-----------+---------+-------+---------+-------------+