在小MEMORY表中的主键上简单常量选择非常慢

时间:2011-10-25 10:26:19

标签: mysql performance memory-table

我有一个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。所以它有一个很长的尾巴。

我完全不知道是什么原因引起的。有人想过吗?

1 个答案:

答案 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平均而非500ms98%比平均值快。

道德:

  • 使用slow query log,对其进行分析,并改进慢查询
  • 如果您遇到莫名其妙的减速,请始终检查“交叉”查询,通过锁定同一个表来减慢查询速度