HN 日本語サマリー

← 一覧へ戻る
プログラミング

pgrust を削除:エントリは不正行為(クエリごとのカーネルと結果キャッシュ)

Remove pgrust: the entry is cheating (github.com)

161 pointsby f311a99 コメント

要約

ClickBench ベンチマークから `pgrust` エントリが削除されました。その理由は、`pgrust` が43個の ClickBench クエリ専用に書かれたコードを使用し、さらに実行結果をキャッシュして再利用していたためです。これはベンチマークのルール(クエリ結果キャッシュの無効化)に違反しており、`tuned: no` とタグ付けされているにも関わらず、特定のクエリに対してチューニングされていたことが指摘されています。この不正行為により、`pgrust` の結果はベンチマークの本来のパフォーマンスを測定するものではないと判断されました。

全文翻訳

pgrust を削除:エントリは不正行為(クエリごとのカーネルと結果キャッシュ) - #2165

このプルリクエストは、ベンチマークから pgrust エントリ(#1163 で追加され、#2106 で v0.4-preview に更新)を削除します。報告されている結果は、43個の ClickBench クエリ専用に書かれた仕組みによって生成されており、ホットランでは前回の実行結果をキャッシュして再利用しています。これらは両方ともルールに違反しています。クエリ結果キャッシュおよびパイプラインの終端に近いキャッシュは無効にする必要があり、エントリはこれらの正確なクエリのためにチューニングされているにも関わらず tuned: no とタグ付けされています。

以下はすべて、公開されている v0.4-preview リリースバイナリ(pgrust.com/downloads/v0.4-preview/、「install」がダウンロードするもの)および公開されている v0.3 ソース(github.com/malisper/pgrust)に対して検証されました。v0.4-preview のソースは公開されておらず、バイナリは pgrust 0.3-beta として識別されます。

ベンチマーククエリごとに1つの手書きカーネル

aarch64 リリースバイナリには、これらのソースパスが埋め込まれています。

crates/gravity/backend/irprobe/src/q00.rs  q01.rs  q02.rs  q03.rs  q04.rs  q06.rs  q07.rs
q12.rs  q15.rs  q16.rs  q17.rs  q18.rs  q19.rs  q20.rs  q21.rs  q22.rs  q23.rs  q24.rs
q25.rs  q27.rs  q30.rs  q31.rs  q36.rs  tpch_q01.rs

数字は ClickBench のクエリ番号です。これらのカーネルにディスパッチするプランマッチャーは、例えば以下のような、ベンチマークの名前にちなんだ拒否メッセージを発します。

clickbench group count: filter is not `k <> 0`
clickbench phrase-min: the third column is not count(*)
clickbench t3 distinct: min(text) / LIKE need one text key, count(*) and the count order
clickbench frame: date_trunc unit is not minute
tpch q1: column 6 is not sum(price * (1 - discount) * (1 + tax))

また、PGRUST_GRAVITY_Q20_VARIANT という名前の環境ノブもあります。

公開されている v0.3 ソースは、この設計を確認しています。crates/backend/executor/sqe/rig/plans/clickbench.ron は、そのヘッダーで「すべての43個の ClickBench クエリに対する手動で低レベル化された物理プラン」と説明されており、queries-clickbench.sql(正確なベンチマーク SQL)は include_str! を使用してエグゼキュータクレートにコンパイルされています。そのファイルは、Q0、Q1、Q2、Q3、Q6、Q19、Q29 を MetadataAnswer(パーティションごとの統計情報から回答され、スキャンなし)として分類し、Q19 の「回答行は述語定数から再構築される」こと、Q29 は代数的書き換え SUM(x+k) = SUM(x) + k*COUNT の後にメタデータ回答が行われること、そして Q18 は永続化された派生列「ビット幅が26/6/20で焼き付けられている」ことに依存することを指摘しています。Q28 の正規表現は、1つのエントリを持つハードコードされたテーブル(HOST_EXTRACT_PATTERN = ^https?://(?:www\.)?([^/]+)/.*$)であり、プランナーのコメントには「43個のクエリの中で唯一の HAVING の形状:COUNT() > k」とあります。

ホットランは結果キャッシュである

Q20、Q21、Q23 について、プランノートには「ホットリプレイ = キャッシュされた判定結果の純粋な折り畳み — ゼロカラムが触れられる; 選択が回答となる」とあります。リリースバイナリでの EXPLAIN は、Q20 では SQE: engine (family: windowreplay)、Q1 では family: metaanswer と報告され、スキャンは never executed とマークされています。

96コアの Graviton (Neoverse-V2) マシンで、エントリ自身のスクリプトと設定を使用し、ドライバーが行うような真のコールドサイクル(停止、キャッシュクリア、起動)でローカルで測定しました。

クエリコールド2回目の実行3回目の実行同じ形状、新しい定数、1回目の実行
Q20 URL LIKE '%google%'10.8 秒11 ミリ秒5 ミリ秒'%rambler%': 283 ミリ秒、その後 12 ミリ秒、4 ミリ秒
Q17 GROUP BY UserID, SearchPhrase LIMIT 101.65 秒4 ミリ秒15 ミリ秒
Q33 GROUP BY URL ORDER BY c DESC LIMIT 102.38 秒213 ミリ秒108 ミリ秒

2回目の再起動で Q20 は 11.2 秒、その後 3 ミリ秒に戻りました。エンジンが実際にウォームな状態でのサブストリングスキャンの速度は数百ミリ秒ですが、これは ClickHouse が同じハードウェアで実行する速度とほぼ同じです。公開されているホットランの数値(Q20 で 7~23 ミリ秒)は、前回の実行結果の判定結果をリプレイしたものです。

v0.2 の提出(#1163)では、同様のキャッシュ(pgrust.condition_cache = on)を開示し、それをオフにすることを提案しました。v0.4 の更新では、その README と設定が削除されました。現在、キャッシュを無効にする設定はありません。pgrust.gravity_entry = off および pgrust.condition_cache = off としても、繰り返し実行される LIKE は依然として 3~4 ミリ秒で返されます。

43個の形状以外のクエリは拒否される

エンジンには、カラム型テーブルに対する一般的な実行パスがありません。わずかに変更されたベンチマーククエリは ERROR: sqe: statement over columnar relation "hits" is not served というエラーで失敗し、エラー詳細は「sqe エンジンはフォールバックなしでカラム型形状を提供します。提供されない形状は、遅く実行されるのではなく、大きな音で失敗します」と述べています。67個のニアベンチマークプローブのうち20個と、49個の変更されたバリアントのうち3個が拒否されました。これには以下が含まれます。

SELECT MIN(URL) FROM hits;
SELECT COUNT(*) FROM hits WHERE URL = 'http://holodilnik.ru/';
SELECT AVG(UserID + 1) FROM hits;
SELECT SUM(ResolutionWidth * 2) FROM hits;
SELECT MAX(length(URL)) FROM hits;
SELECT COUNT(*) FROM hits WHERE strpos(URL, 'google') > 0;
SELECT COUNT(*) FROM (SELECT UserID FROM hits GROUP BY UserID) t;
SELECT SearchPhrase, COUNT(*) AS c FROM hits WHERE SearchPhrase <> '' GROUP BY SearchPhrase HAVING SUM(IsRefresh) > 10 ORDER BY c DESC LIMIT 10;
SELECT REGEXP_REPLACE(Referer, '^https?://(?:www\.)?([^/]+)/.*$', '\1', 'g') AS k, ... -- the Q28 regexp with a flag

INSERT、UPDATE、DELETE もテーブルではサポートされていません(pgrcolumnar2 does not support INSERT)。

記録のために

43個のクエリ自体の回答は正確です。同じ hits.parquet に対して clickhouse local と比較すると、30個が完全に一致し、残りの違いは LIMIT クエリにおける有効なタイブレークです(個別に検証済み)。問題は間違った結果ではなく、結果がデータベースではなくベンチマークのルックアップテーブルを測定していることです。

関連: #1163
関連: #2106