0

我有一个大约 650 行、5 MB 数据长度、60 kB 索引长度的 MEMORY 表(所以它非常小)。它有一个 SMALLINT 主(散列)键和大约 90 个其他列(整数、varchars、日期时间,没有 blob 或文本)。(编辑:BIGINT 列上还有一个哈希键。)

我经常(大约每秒 10 次)运行这个查询(来自 PHP):

select * from userek where id={CONST_ID} and kitiltva=0 and kitiltva_meddig<"{CONST_DATETIME}" and inaktiv=0

注意:id是主键。我需要,*因为结果在很多不同的地方使用,基本上所有的列都在这里或那里使用。

我的问题是:查询定期变得异常缓慢。大约0.5s平均,8s最大。大多数时候它非常快:75%运行速度比快3ms85%比平均速度快。但15%它比平均速度13%慢,比1s. 所以它的尾巴很长。

我完全不知道是什么原因造成的。有什么想法吗?

4

1 回答 1

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、分析和改进慢查询
  • 如果您遇到莫名其妙的减速,请始终检查通过锁定同一张表来减慢查询速度的“交叉”查询
于 2011-10-25T20:02:14.837 回答