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 |
+----+-------------+---------------+------+------------------------------------------------------------------+-----------+---------+-------+---------+-------------+