我收集了诊断结果,但我不确定为什么会这样。我没有看到任何大的锁时间,或者大量的子查询被意外运行。
查询:
SELECT message, level, logged_at FROM application_logs
WHERE application_id = 5 AND
message NOT LIKE '(build)%' AND
logged_at >= (
SELECT launched_at
FROM application_sessions
WHERE application_id = 5
ORDER BY id DESC LIMIT 1
)
ORDER BY id DESC LIMIT 500;
我对每个连接到站点的用户运行此查询1次。它目前以大约6/秒的速度运行,并且需要很长时间,这是一个大问题。
表application_logs
约为2。500万行和application_sessions
约20 k行。我可能应该清除application_logs〈7天或什么。
解释:它还在运行,裸露着
慢查询日志:
SELECT message, level, logged_at
FROM application_logs
WHERE application_id = 9 AND message NOT LIKE '(build)%'
AND logged_at >= (
SELECT launched_at
FROM application_sessions
WHERE application_id = 9
ORDER BY id DESC LIMIT 1
)
ORDER BY id DESC LIMIT 100;
用户@Host:remote[remote] @ [**************] Thread_id:14180方案:****QC_hit:无查询时间(_T):21.056101锁定时间:0.000102行_已发送:19行_已检查:233153 Rows_effected:0字节(_sent):3421
SET timestamp=1681832466;
SELECT message, level, logged_at
FROM application_logs
WHERE application_id = 9 AND message NOT LIKE '(build)%'
AND logged_at >= (
SELECT launched_at
FROM application_sessions
WHERE application_id = 9
ORDER BY id DESC LIMIT 1
) ORDER BY id DESC
LIMIT 100;
1条答案
按热度按时间ttcibm8c1#
application_logs
表上的查询如下所示,其中WHERE子句重新排序。在查询中编写的子句的顺序对性能没有影响;我重新安排了它们,只是为了帮助解释事情。您可以在该表上使用multicolumn覆盖索引来加速此查询。
使用BTREE索引类似于访问表中行的排序列表。您的查询使用此索引,如下所示。
1.它使用所需的
application_id
和大于所需起始点的第一个logged_at
值(来自子查询)随机访问第一行的索引。1.然后,它按顺序访问 index(而不是 table),查找与
message NOT LIKE
子句匹配的行。1.它按您想要的顺序取出
id
值,并在达到限制时停止扫描。试试看,可能会有帮助。
通过类似的逻辑,您的子查询可以从这个索引中受益。
服务器可以随机访问所需行的索引,并检索该行的
launched_at
列,非常快。要获得理解这类事情所需的信息,请执行prefix your query with
EXPLAIN
。然后examine EXPLAIN输出。Read this for a more thorough explanation。