0

約650行、5 MBのデータ長、60 kBのインデックス長のMEMORYテーブルがあります(かなり小さいです)。1つのSMALLINTプライマリ(ハッシュ)キーと、約90の他の列(int、varchars、datetimes、blobまたはtextsなし)があります。(編集:BIGINT列にもハッシュキーがあります。)

私はこのクエリを(PHPから)かなり頻繁に実行しています(1秒間に約10回):

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ところ、この特定のテーブル(および他のテーブル)を使用している2つの頻繁で遅い選択が見つかりました。原因は、ケースの結合が正しく形成されていないことでした。

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 に答える