我有一个MEMORY表,大约650行,5 MB数据长度,60 kB索引长度(因此它非常小)。它有一个SMALLINT主(哈希)键,以及大约90个其他列(整数,变量,日期,无blob或文本)。 (编辑:BIGINT列上还有一个哈希键。)
我经常运行此查询(来自PHP)(大约每秒10次):
从userek中选择*,其中id = {CONST_ID}且kitiltva = 0和 kitiltva_meddig<“{CONST_DATETIME}”和inaktiv = 0
注意:id
是主键。我需要*
,因为结果在很多不同的地方使用,基本上所有列都在这里或那里使用。
我的问题是:查询定期异常缓慢。平均约为0.5s
,最多8s
。大多数情况下它的速度非常快:75%
的运行速度比3ms
快,85%
比平均速度快。但是15%
它比平均值慢,13%
慢于1s
。所以它有一个很长的尾巴。
我完全不知道是什么原因引起的。有人想过吗?
答案 0 :(得分:0)
很抱歉回答我自己的问题,但至少我有一个答案。我试着以对别人有帮助的方式来写它。
由于它是一个MEMORY表,我排除了I / O问题。
接下来,查询是主键的简单(const)选择,因此它也不能成为索引问题。
下一个猜测是锁定。我的应用程序在这个表上有一些非常慢的选择。这可能是一个问题:慢选择延迟其他选择的延迟更新,所以最后这个非常简单和快速的选择可以延迟。
我检查了slow query log
,发现了两个使用此特定表的频繁和慢速选择(以及其他表)。原因是案件的连接形成不良:
A left join B on case
when A.x=1 then B.id=A.id2
when A.x=2 then B.id=A.id3
else B.id=0
end
而不是
A left join B on B.id = case
when A.x=1 then A.id2
when A.x=2 then A.id3
else 0
end
两者都给出相同的结果,但后者可以使用B.id
的索引,前者不能。
我更正了这些查询后,原始查询的效果得到了极大的提升:5ms
平均而非500ms
。 98%
比平均值快。
道德:
slow query log
,对其进行分析,并改进慢查询