PREWHERE句
Prewhereは、フィルタリングをより効率的に行うための最適化です。PREWHERE句が明示的に指定されていない場合でも、デフォルトで有効になっています。これは、WHERE条件の一部をprewhereステージに自動的に移動させることで機能します。PREWHERE句の役割は、デフォルトの動作よりも良い方法を知っていると思う場合に、この最適化を制御することだけです。
prewhere最適化を使用すると、最初にprewhere式を実行するために必要なカラムだけが読み取られます。その後、クエリの残りを実行するために必要な他のカラムが読み取られますが、prewhere式が少なくともいくつかの行でtrueであるブロックのみです。すべての行に対してprewhere式がfalseであるブロックが多数あり、prewhereで必要とされるカラムがクエリの他の部分よりも少ない場合、クエリの実行のためにディスクから読むデータを大幅に減らすことができることがよくあります。
Prewhereの手動制御
この句はWHERE句と同じ意味を持ちます。違いは、テーブルからどのデータが読み取られるかにあります。フィルタリング条件に対してPREWHEREを手動で制御すると、クエリ内のカラムの少数によって使用されるが、強力なデータフィルタリングを提供する条件を指定します。これにより、読まれるデータのボリュームが減少します。
クエリは同時にPREWHEREとWHEREを指定できます。この場合、PREWHEREがWHEREの前に来ます。
もしoptimize_move_to_prewhere設定が0に設定されている場合、WHEREからPREWHEREへ自動的に部分式を移動させるためのヒューリスティックが無効になります。
クエリがFINAL修飾子を持っている場合、PREWHEREの最適化が常に正しいとは限りません。これは、optimize_move_to_prewhereとoptimize_move_to_prewhere_if_finalの両方の設定がオンになっている場合のみ有効です。
PREWHEREセクションはFINALの前に実行されるため、テーブルのORDER BYセクションにないフィールドでPREWHEREを使用した場合、FROM ... FINALクエリの結果が偏る可能性があります。
制限事項
PREWHEREは、*MergeTreeファミリーのテーブルでのみサポートされています。