当前位置: 首页 > 知识库问答 >
问题:

2个类似的查询在MySQL中,2个性能差别很大,为什么?

方璞
2023-03-14

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

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)

问题是InnoDB更改了查询使用的索引。我的问题很简单,为什么会发生这种情况?

共有1个答案

皮骏
2023-03-14

在一本书的索引中,为什么不包括像“the”或“and”这样的常用词呢?因为它会匹配书中的每一页,而且在索引中查找值没有用。你还不如从头到尾读完这本书的所有页。

如果MySQL估计该条件将匹配很大比例的行,MySQL将不会使用索引。确切的阈值没有文档,但根据我的经验,它大约是表的20-25%。请注意,MySQL索引统计信息并不总是完美的;它们是基于抽样数据的估计。

在第二个查询中,日期的范围条件略宽。因此,它匹配更多的行。这可能刚好超过阈值,所以MySQL决定不使用i_event2索引。

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' ;
ALTER TABLE event ADD INDEX i_event_survey_datez (survey_id, event_datez);
 类似资料:
  • 问题内容: 我有这个查询 和同一个1差异。不是 1周 ,而是 1个月 ,我该如何合并这两个并将它们分配给别名? 问题答案: 我将使用条件聚合来做到这一点: MySQL将布尔值视为整数,即为“ true”和“ false”。因此,使用可以计算匹配值的数量。(在其他数据库中,您将使用进行类似的操作。)

  • 问题内容: 我有2个查询,如下所示: 第二个: 我如何在这两者之间划分计数?它将始终仅返回2个值,一个将称为Exp,而一个将称为NonExp。 谢谢 问题答案: 基本上将这两个查询视为子查询,如下所示。 如果您想更进一步,则可以将cvu.id作为选择和修改联接的一部分,以便可以在所有cvu.id的

  • 问题内容: 我有一张表如下 预期输出:name8,name7,name6,name3,name2 我希望在每个类别中显示最后2个条目吗?有人请帮帮我。谢谢你的放心。 问题答案: 这些类型的结果最好由其他RDBMS中的窗口函数来处理,但是不幸的是Mysql没有任何窗口函数,因此作为替代方案,存在一种使用用户定义的变量为属于同一组的行分配等级的解决方案。 上面的查询将为您提供每个类别2条最近记录(基于

  • 问题内容: 我有这3张表。 我创建了用于创建订单的表单,其中填写了订单(日期)的信息以及完成订单的人。在我的表单中,有一个表格可供我选择员工并获取其ID。我想知道是否可以通过一个查询将表Order和completelyBy插入表中。 使用两个插入内容或使用答案中的代码之间在有效性上有什么区别吗? 问题答案: 这可以使用修改公共表表达式的数据来完成: 第一部分插入表中并返回插入的ID。然后,第二部分

  • 问题内容: 每个表(表1和表2)都有其自己的DATETIME字段。 我正在尝试捕获两个表的ID,并按其DATETIME字段对其进行排序。 例子: 我的输出未通过以下查询正确排序: 所需数据: 来自表2 id:2、1, 来自表1 id:3、2、1 因此:2、1、3、2、1 ////编辑 对于可能会遇到冗长而复杂的MySQL请求的人们,请在PhpmyAdmin中尝试一下!它会告诉您错误! ////编辑

  • 问题内容: 我想为每行乘以2个单元格,并将其值放在称为Total的最后一列中。可以通过常规查询来完成吗? 例: 问题答案: 用这个: