2017-02-09 2 views
0

効率的にセットアップが簡単にできませんでした:H2データベース・パフォーマンス・ストレンジネス---またはどのように `COUNT(*)`

  • H2バージョン1.3.176
  • 一つのテーブル、二つがありそのうち10列ビット長が300〜3500文字の標準値の長さ
  • 簡易クエリ:select count(*) from requestrepository where request_type = 'ADD'
  • インデックスは照会列にあります。
  • 問合せ対象列だけVARCHAR(20)(長いものの即ちないもの)
  • 問合せ対象の列が一つ200K回出現し、その他12万回の出現と、ちょうど2つの異なる値を含んでいます。 (0)、analyzeを実行します(1)で1行を削除:
  • DBは、Java 8、現在のSSD、現在のサーバのハードウェアを、オフに実行し

私は何をすべきか(ビットが、結果の変化なしを変えます) (2)削除したばかりのキーの行を1つ挿入します。(3)上記のクエリを実行し、10までカウントして繰り返します。私が見

:クエリは、上記の引用は、3と5秒の間、それぞれの時間がかかり、explain analyzeは言う:

SELECT 
    COUNT(*) 
FROM PUBLIC.REQUESTREPOSITORY 
    /* PUBLIC.IX_REQUESTS: REQUEST_TYPE = 'ADD' */ 
    /* scanCount: 12098748 */ 
WHERE REQUEST_TYPE = 'ADD' 
/* 
REQUESTREPOSITORY.IX_REQUESTS read: 126700 
*/ 

私は/ VM/Windowsの、ハードウェア/ Linuxの/ SSD、別のマシンで同じDBを試してみましたnetappですが、傾向は常に同じです:count(*)は(?)長くかかります。

これはわかりません。これには時間がかかりますか?私は少なくとも2回目はキャッシュがいっぱいだと思っていたでしょうが、これははるかに速くなければなりませんが、explain analyzeは常に126700リードをリストしています。

H2パラメータまたは設定についてのヒントはどのように改善されるのでしょうか。

EDIT(これはむしろ答えになるべきかどうか分かりません) 私たちは、mvstore、1.4.x、並列スレッド、異なるディスク、Linux、Windowsを持つコンピュータなど、幅広いものを試しました。状況は常に同じです。処理、追加、削除、列のインデックス、1つのステータスが大過剰に表示されているような3つのステータス値を持つvarchar列を取る:count(*) where colname='ADD'のようなものは、表。

この問題を回避するために、私たちは最終的にオンデマンドではなく、group byのコードではなく、という3つのコードを各ステータスごとに1つずつ作成し、5秒ごとに実行しました。確かに私たちが持っていた最高のデザインではありません。

私が持っている唯一の言い訳は、このような設定ではcount(*)が長くかかることに私はまだ驚いています。私の見方は、実際には更新後にカウントすることによって、その数をインデックス上で計算しなければならないということですが、私はその数をちょうどどこかのデータ構造から読み取ることができると予想しました。 (批判はありませんが、自分でDBを実装することはできません)

+0

最新バージョンのH2(MVStore形式)をお試しになりましたか? –

答えて

0

H2についてはわかりませんが、COUNT(*)の代わりにCOUNT(request_type)を試してみましたか?

SQL標準のCOUNT(*)は、NULL値のみで構成される行を除外するために全テーブルスキャンが必要なため、計算に時間がかかる傾向があります。

COUNT()を単一の索引付き列に使用すると、処理速度が向上します。この方法では、索引は列の値がNULLかどうかを判断するのに十分なので、表の行を読み取る必要はありません。

関連する問題