MySQL中有2个类似的查询,2个性能非常不同,为什么?

MySQL中有2个类似的查询,2个性能非常不同,为什么?,mysql,innodb,Mysql,Innodb,我们有一个相当大的数据库,我们在其中查询一组基于日期时间列的数据库。昨天我们遇到了一个问题,我们发现一个通常需要4秒的特定查询现在需要超过40秒 经过一些挖掘和调试,我们发现了问题 mysql> explain select count(*) from event where survey_id = 158 and event_datez>'2019-10-30 00:00:00' and event_datez<'2019-11-28 23:59:59' ; # Query

我们有一个相当大的数据库,我们在其中查询一组基于日期时间列的数据库。昨天我们遇到了一个问题,我们发现一个通常需要4秒的特定查询现在需要超过40秒

经过一些挖掘和调试,我们发现了问题

mysql> explain select count(*) from event where survey_id = 158 and event_datez>'2019-10-30 00:00:00' and event_datez<'2019-11-28 23:59:59' ; # Query takes 4s
+----+-------------+--------------+------------+-------+-----------------------------------------------+------------------+---------+------+---------+----------+------------------------------------+
| id | select_type | table        | partitions | type  | possible_keys                                 | key              | key_len | ref  | rows    | filtered | Extra                              |
+----+-------------+--------------+------------+-------+-----------------------------------------------+------------------+---------+------+---------+----------+------------------------------------+
|  1 | SIMPLE      |        event | NULL       | range | FK_g1lx0ea096nqioytyhtjng72t, i_event_2       | i_event_2        | 6       | NULL | 2975160 |    50.00 | Using index condition; Using where |
+----+-------------+--------------+------------+-------+-----------------------------------------------+------------------+---------+------+---------+----------+------------------------------------+
1 row in set, 1 warning (0.00 sec)

mysql> explain select count(*) from event where survey_id = 158 and event_datez>'2019-10-29 00:00:00' and event_datez<'2019-11-28 23:59:59' ; # Query takes 40s
+----+-------------+--------------+------------+------+-----------------------------------------------+------------------------------+---------+-------+----------+----------+-------------+
| id | select_type | table        | partitions | type | possible_keys                                 | key                          | key_len | ref   | rows     | filtered | Extra       |
+----+-------------+--------------+------------+------+-----------------------------------------------+------------------------------+---------+-------+----------+----------+-------------+
|  1 | SIMPLE      | event        | NULL       | ref  | FK_g1lx0ea096nqioytyhtjng72t,i_event_2        | FK_g1lx0ea096nqioytyhtjng72t | 9       | const | 16272884 |    12.23 | Using where |
+----+-------------+--------------+------------+------+-----------------------------------------------+------------------------------+---------+-------+----------+----------+-------------+
1 row in set, 1 warning (0.00 sec)

mysql>解释从事件中选择计数(*),其中调查id=158和事件日期>'2019-10-30 00:00:00'和事件日期解释从事件中选择计数(*)从事件中选择计数(*),调查id=158和事件日期>'2019-10-29 00:00:00'和事件日期在一本书的索引中,为什么不包括诸如“或”和“和”之类的常用词?因为它会匹配书中的每一页,而在索引中查找值是没有用的。你不妨把书中的每一页都读一遍

如果MySQL估计条件将匹配大部分行,则不会使用索引。精确的阈值没有记录,但根据我的经验,它大约占表的20-25%。请注意,MySQL索引统计数据也并不总是完美的;它们是基于抽样数据的估计

在第二个查询中,日期的范围条件稍宽一些。因此,它匹配更多行。这可能只是超出了阈值,所以MySQL决定不使用
i_event_2
索引

MySQL也可能会稍微偏爱使用
type:ref
而不是
type:range
的查询优化计划

你可以使用一个MySQL只考虑<代码> IyEngult2 index。

select count(*) from event USE INDEX (i_event_2)
where survey_id = 158
  and event_datez>'2019-10-29 00:00:00' 
  and event_datez<'2019-11-28 23:59:59' ;

你能发布FK_g1lx0ea096nqioytyhtjng72t和i_事件_2的索引吗?在日期上,我会做的少于以下日期。它不够精确,无法使用,所以我们同意。。。少于以下日期。@DRapp-否。请改为在第二天执行
<00:00:00
。这适用于DATE、DATETIME和DATETIME(6)。我明白这就是DRapp所说的。
ALTER TABLE event ADD INDEX i_event_survey_datez (survey_id, event_datez);