時系列クエリのパフォーマンス
ストレージを最適化した後の次のステップは、クエリパフォーマンスの向上です。このセクションでは、ORDER BY
キーの最適化とマテリアライズドビューの使用という 2 つの重要な技術を探ります。これらのアプローチによって、クエリの実行時間を秒からミリ秒に短縮する方法を見ていきます。
ORDER BY キーの最適化
他の最適化を試みる前に、ClickHouse ができるだけ迅速な結果を生成できるように、オーダリングキーを最適化する必要があります。キーの選択は、実行するクエリに大きく依存します。たとえば、ほとんどのクエリが project
および subproject
カラムでフィルタリングされる場合、この場合には、時間カラムに加えてオーダリングキーにこれらを追加することが良いアイデアです。
同じカラムタイプを持ち、(project, subproject, time)
でソートされたテーブルの別バージョンを作成しましょう。
次に、パフォーマンスに対するオーダリングキーの重要性を理解するために、複数のクエリを比較してみましょう。前回のデータタイプおよびコーデックの最適化を適用していないため、クエリパフォーマンスの違いはソート順にのみ基づいています。
クエリ | (time) | (project, subproject, time) |
---|---|---|
2.381 sec | 1.660 sec | |
2.148 sec | 0.058 sec | |
2.192 sec | 0.012 sec | |
2.968 sec | 0.010 sec |
マテリアライズドビュー
もう 1 つのオプションは、マテリアライズドビューを使用して人気のあるクエリの結果を集約して保存することです。これらの結果は、元のテーブルの代わりにクエリすることができます。たとえば、次のクエリがよく実行される場合を考えてみましょう。
マテリアライズドビューの作成
次のマテリアライズドビューを作成できます。
宛先テーブルのバックフィル
この宛先テーブルは、wikistat
テーブルに新しいレコードが挿入されるときにのみ populated されるため、バックフィルを行う必要があります。
これを行う最も簡単な方法は、INSERT INTO SELECT
ステートメントを使用して、マテリアライズドビューのターゲットテーブルに直接挿入することであり、ビューの SELECT クエリ (変換) を使用することです。
生データセットのカーディナリティによっては (1億行を持つ!)、この方法はメモリ集約的になる場合があります。あるいは、最小限のメモリを必要とするバリアントを使用できます。
- Null テーブルエンジンを持つ一時テーブルを作成
- 通常使用されるマテリアライズドビューのコピーをその一時テーブルに接続
- INSERT INTO SELECT クエリを使用して、生データセットからその一時テーブルにすべてのデータをコピー
- 一時テーブルと一時マテリアライズドビューを削除
そのアプローチでは、生データセットの行が一時テーブルにブロック単位でコピーされ(これらの行は保存されません)、各ブロックの行に対して部分的な状態が計算され、ターゲットテーブルに書き込まれ、これらの状態がバックグラウンドで増分的にマージされます。
次に、wikistat_backfill
から読み取り、wikistat_top
に書き込むマテリアライズドビューを作成します。
そして最後に、初期の wikistat
テーブルから wikistat_backfill
を populate します。
そのクエリが完了すると、バックフィルテーブルとマテリアライズドビューを削除できます。
これで、元のテーブルの代わりにマテリアライズドビューをクエリできます。
ここでのパフォーマンス改善は劇的です。以前はこのクエリの結果を計算するのに 2 秒以上かかっていましたが、現在はわずか 4 ミリ秒です。