PREWHERE を使用すると、読み取るデータ量を削減し、フィルタリングを効率化できます。デフォルトでは、クエリで PREWHERE を明示的に指定していなくても、ClickHouse は対象となる条件を WHERE から PREWHERE に移動して、この最適化を適用します。この段階で適用する条件を制御するには、PREWHERE を明示的に指定します。
PREWHERE では、ClickHouse はまず条件の評価に必要なカラムだけを読み取ります。次に、一致する行を少なくとも 1 行含むブロックに対してのみ、クエリで必要な他のカラムを読み取ります。条件で使用するカラム数がクエリの他の部分より少なく、多くのブロックを除外できる場合、読み取るデータ量を削減できます。
PREWHERE を手動で制御する
PREWHERE を手動で指定します。これにより、残りのカラムから読み取るデータ量を削減できます。
クエリには PREWHERE と WHERE の両方を含めることができます。この場合、PREWHERE が先に評価されます。
ClickHouse が条件を WHERE から PREWHERE に自動的に移動しないようにするには、optimize_move_to_prewhere を 0 に設定します。
FINAL 修飾子を使用するクエリでは、optimize_move_to_prewhere と optimize_move_to_prewhere_if_final の両方が有効な場合にのみ、ClickHouse は条件を WHERE から PREWHERE に移動します。
デフォルトでは
PREWHERE は FINAL より先に評価されるため、PREWHERE がテーブルの ORDER BY キーに含まれないカラムを参照している場合、FROM ... FINAL クエリは予期しない結果を返す可能性があります。JOIN を使用する PREWHERE
JOIN を含むクエリでは、PREWHERE 条件が直接参照できるカラムは最大で1つのテーブルに限られます。ClickHouse は、結合前にそのテーブルの行に条件を適用します。
一方、WHERE 条件は論理上、結合結果をフィルタリングします。ただし、結果が変わらない場合、オプティマイザによって結合前に適用されることがあります。そのため、同じ条件を PREWHERE と WHERE で使用すると、特に外部結合では結果が異なる場合があります。
次の例では、この違いを示すために2つのテーブルを作成します。
PREWHERE により LEFT JOIN の前に table_2 がフィルタリングされるため、table_1 の id = 1 の行は結合先がないまま残ります:
WHERE で同じ条件を使用すると、結合結果がフィルタリングされ、id = 1 の行が除外されます。
制限事項
PREWHERE は、*MergeTree ファミリーのテーブルでのみサポートされています。