mysql - 真的很长的mysql查询然后真的很快
问题描述
我对 SQL 查询有一个奇怪的行为,我真的不明白。
这是我的查询:
SELECT DISTINCT SU.a
FROM SU
INNER JOIN SUT ON SUT.id = SU.tid
WHERE SUT.id = 1
AND SUT.status != 'DELETED'
AND SU.status != 'DELETED'
ORDER BY SU.a
LIMIT 1;
第一次运行时,运行需要 8 分钟:
# Time: 2021-07-13T15:14:24.655492Z
# User@Host: a @ localhost [] Id: 12778294
# Schema: a Last_errno: 0 Killed: 0
# Query_time: 472.123927 Lock_time: 0.000122 Rows_sent: 1 Rows_examined: 2055628 Rows_affected: 0 Bytes_sent: 132
但是当它第二次运行时,它真的很快:
# Time: 2021-07-13T15:27:24.286939Z
# User@Host: a @ localhost [] Id: 12786055
# Schema: a Last_errno: 0 Killed: 0
# Query_time: 3.099028 Lock_time: 0.000124 Rows_sent: 1 Rows_examined: 2055642 Rows_affected: 0 Bytes_sent: 132
查询的解释似乎很好:
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+---------------------+------------+-------+----------------------------------------------------------+--------------------------+---------+-------+------+----------+-------------+
| 1 | SIMPLE | SUT | NULL | const | PRIMARY | PRIMARY | 4 | const | 1 | 100.00 | NULL |
| 1 | SIMPLE | SU | NULL | index | u_SU_a,idx_SUT_status | u_SU_a | 8 | NULL | 4725 | 0.08 | Using where |
+----+-------------+---------------------+------------+-------+----------------------------------------------------------+--------------------------+---------+-------+------+----------+-------------+
两次执行之间的差异非常大。主机是一个大型 VM,在 Azure 上具有 55G 内存和 SSD Premium(P30 - 5000 IOPS,200 MBps)
解决方案
简短的回答:你看到的是正常的。
长答案:
如果第二次大约是 0.001 秒,我会怀疑查询缓存。但由于是 3 秒,我怀疑是其他缓存。
注意“Rows_examined”大约是 200 万。在非常糟糕的情况下,这可能是 2M 磁盘命中。使用 HDD,这可能需要大约 20K 秒;使用 SSD,可能不到 2K 秒。
由于第一次运行只用了 472 秒,我怀疑缓存(innodb_buffer_pool)在执行期间部分有用。可能只需要读取 47200 个块(如果使用 HDD)。
第二次运行显然在缓存中找到了所有必要的块,使其受 CPU 限制,没有 I/O。因此,只有 3 秒。
第三次运行将再次约为 3 秒。等等。
稍后,如果出现其他一些大查询并将块从缓存中取出,查询将再次变慢。
如果您提供SHOW CREATE TABLE
每个表,我们可能会建议更好的索引,以使其在第一次和以后的时间都运行得更快。
推荐阅读
- excel - Excel 数据透视表,需要显示总计,包括按类别过滤的项目
- javascript - JavaScript 错误:TypeError:无法读取未定义的属性“集”
- android - Xamarin / Android 构建
- javascript - Fullcalendar 多月活动
- linux - 无法在 linux 上安装最新版本的 chromium 和 chromium-chromedriver(alpine3.9 docker 镜像)
- python - 在 Python 中反转列表的特定切片
- android - 带有外部库的 Xamarin Android 无法解析 R$attr
- azure - 当 Azure 服务总线消息无法保存在队列中并且它们相互依赖时,如何处理 Sql Server 回滚?
- c# - EF Core 5.0.5 Add-Migration 字符串参数“名称”不能为空
- javascript - 更新多级对象数组中的属性