为什么mysql没有使用正确的索引?

为什么mysql没有使用正确的索引?,mysql,query-optimization,Mysql,Query Optimization,我有一个问题,没有使用正确的索引 我在innodb表上有以下索引(大约500000行): 此查询: EXPLAIN EXTENDED SELECT user.id, user.active FROM osdate_user user WHERE user.active =1 AND user.status = 'active' AND user.gender = 'M' AND user.age BETWEEN 19 AND 35 AND user.pictures_cnt >0

我有一个问题,没有使用正确的索引

我在innodb表上有以下索引(大约500000行):

此查询:

EXPLAIN EXTENDED SELECT user.id, user.active
FROM osdate_user user
WHERE user.active =1
AND user.status =  'active'
AND user.gender =  'M'
AND user.age
BETWEEN 19 
AND 35 
AND user.pictures_cnt >0
AND user.private_photos =  '0'
ORDER BY user.lastvisit DESC 
LIMIT 0 , 24
显示以下平面:

+----+-------------+---------+-------------+--------------------------------------------------------------+------------------------------+---------+---------------------------+-------+----------+----------------------------------------------------------------------------+
| id | select_type | table   | type        | possible_keys                                                | key                          | key_len | ref                       | rows  | filtered | Extra                                                                      |
+----+-------------+---------+-------------+--------------------------------------------------------------+------------------------------+---------+---------------------------+-------+----------+----------------------------------------------------------------------------+
|  1 | SIMPLE      | user    | index_merge | PRIMARY,active,gender,age,private_photos,pictures_cnt,status | gender,private_photos,active | 4,1,2   | NULL                      | 28204 |   100.00 | Using intersect(gender,private_photos,active); Using where; Using filesort |
|  1 | SIMPLE      | userext | eq_ref      | userid                                                       | userid                       | 4       | db_name.user.id |     1 |   100.00 | Using index                                                                |
+----+-------------+---------+-------------+--------------------------------------------------------------+------------------------------+---------+---------------------------+-------+----------+----------------------------------------------------------------------------+
我的问题是为什么查询不使用索引“status”

当我强制它使用索引“status”时,它需要0.2秒,如果我不使用,则需要2.5秒


非常感谢您的帮助。注意。

u有几个索引,它们与索引的字段重叠。 例如
图片\u cnt
状态

优化器“认为”您的查询更接近于使用
图片
的字段,而不是
状态
索引。如果在
中有更多属于
状态索引的字段,它可能会决定使用该索引而不是
图片

请注意,它不能同时使用这两个选项


如果你认为优化器是错误的(在不常见的情况下),你可以强迫它使用你想要它使用的索引。尽管如此,还是要对它进行基准测试。

在搜索了一点之后,我发现了一些建议,建议不要使用允许索引为null的列。我将状态索引中的列全部更改为非空,现在正在使用该索引


通常情况下,最简单、最干净的解决方案是最好的。

可能是因为优化器已经确定这不是进行此查询的最佳方式?您是否尝试并强制使用了它,并比较了时间?此表使用的存储引擎是什么?它有多大?我曾经遇到过一个非常大的InnoDB表的优化器问题,直到我将InnoDB_stats_sample_pages变量从默认值8更改为128。我更新了有关强制索引使用和表信息的信息-强制它使用索引“status”比索引mysql choseapparently快得多(请参见
user.status='active'
)无论如何,您不应该在此列上使用索引。什么是地位基数?3, 4? 如果是,建议不要在此列上设置索引。@因为此列是枚举。请进一步说明?强迫它确实解决了问题,但我不想走这条路。请注意,它没有使用索引图片\u cnt-它只在“可能的索引”中列出
+----+-------------+---------+-------------+--------------------------------------------------------------+------------------------------+---------+---------------------------+-------+----------+----------------------------------------------------------------------------+
| id | select_type | table   | type        | possible_keys                                                | key                          | key_len | ref                       | rows  | filtered | Extra                                                                      |
+----+-------------+---------+-------------+--------------------------------------------------------------+------------------------------+---------+---------------------------+-------+----------+----------------------------------------------------------------------------+
|  1 | SIMPLE      | user    | index_merge | PRIMARY,active,gender,age,private_photos,pictures_cnt,status | gender,private_photos,active | 4,1,2   | NULL                      | 28204 |   100.00 | Using intersect(gender,private_photos,active); Using where; Using filesort |
|  1 | SIMPLE      | userext | eq_ref      | userid                                                       | userid                       | 4       | db_name.user.id |     1 |   100.00 | Using index                                                                |
+----+-------------+---------+-------------+--------------------------------------------------------------+------------------------------+---------+---------------------------+-------+----------+----------------------------------------------------------------------------+