クエリパフォーマンス向上のためのTop-Kプルーニング

SELECT ステートメントに LIMIT 句および ORDER BY 句が含まれる場合、どの行も上位K位(Kは LIMIT 句の値)までの結果に含まれる可能性があるため、Snowflakeは通常、対象となるすべての行をスキャンします。トップKプルーニングにより、Snowflakeは残りのどの行もK件のレコードからなる結果セットに含まれないと判断した時点でスキャンを停止します。

Top-Kプルーニングは、 LIMIT 句および ORDER BY 句を含む SELECT ステートメントのパフォーマンスを向上させます。規模の大きいテーブルをクエリする場合に、トップKプルーニングは最も効果的です。

トップKプルーニングを使用したクエリ

Snowflakeは、以下のすべてが真である場合にのみtop-Kプルーニングを適用します。

  • クエリに ORDER BY 句と LIMIT 句の両方が含まれる。

  • ORDER BY 句で指定された最初の列のデータ型が以下のいずれかである。

    • 整数表現可能なデータ型(すなわち、 INTEGER 型DATE 型、 または TIMESTAMP 型)。キャストなど、整数を返す式はサポートされていません。

    • 文字列またはバイナリデータ型照合文字列 を含む)。

    • VARIANT 列のフィールドで、サポートされている基になる型(つまり、前の2つの箇条書きのリスト項目にリストされている型)を持ち、その基になる型にキャストされたもの。

    複数の列が指定された場合、Snowflakeは最初の列のみを考慮します。

  • クエリに結合が含まれる場合、 ORDER BY 列は大規模なテーブルの列となります。データウェアハウジングでは、大きなテーブルは ファクトテーブル またはプローブ側と呼ばれることがよくあります。小さなテーブルは ディメンションテーブル と呼ばれます。

既に高速な LIMIT 句を持つクエリ(フルテーブルスキャンが高速なクエリなど)は、トップKプルーニングの効果が得られない可能性があります。K行未満の行を返すクエリも効果が得られません。

ORDER BY ... DESCENDING をヌル可能フィールドに含むクエリは、 NULLS LAST も指定されている場合にのみプルーニングされます。

VARIANT 列に対するクエリ

このセクションでは、 VARIANT 列のフィールドに対するクエリの例を紹介し、トップKプルーニングの使用が可能なクエリのタイプを示します。

VARIANT 列を含むテーブルを作成し、データを挿入します:

CREATE OR REPLACE TABLE variant_topk_test (var_col VARIANT);

INSERT INTO variant_topk_test
  SELECT PARSE_JSON(column1)
    FROM VALUES
      ('{"s": "aa", "i": 1}'),
      ('{"s": "bb", "i": 2}'),
      ('{"s": "cc", "i": 3}'),
      ('{"s": "dd", "i": 4}'),
      ('{"s": "ee", "i": 5}'),
      ('{"s": "ff", "i": 6}'),
      ('{"s": "gg", "i": 7}'),
      ('{"s": "hh", "i": 8}'),
      ('{"s": "ii", "i": 9}'),
      ('{"s": "jj", "i": 10}');
Copy

このテーブルは例示を目的とした比較的小さいものですが、トップKプルーニングは大規模なテーブルで効果が高いことを覚えておいてください。

このテーブルに対する以下のクエリにトップKプルーニングを使用できます:

SELECT * FROM variant_topk_test ORDER BY TO_VARCHAR(var_col:s) LIMIT 5;
Copy
SELECT * FROM variant_topk_test ORDER BY var_col:s::VARCHAR LIMIT 5;
Copy
SELECT * FROM variant_topk_test ORDER BY TO_NUMBER(var_col:i) LIMIT 5;
Copy
SELECT * FROM variant_topk_test ORDER BY var_col:i::NUMBER LIMIT 5;
Copy

以下のクエリは、基になるデータ型に値がキャストされていないため、トップKプルーニングを使用できません:

SELECT * FROM variant_topk_test ORDER BY var_col:s LIMIT 5;
Copy

以下のクエリは、基になるデータ型とは異なるデータ型に値がキャストされているため、トップKプルーニングを使用できません:

SELECT * FROM variant_topk_test ORDER BY var_col:i::VARCHAR LIMIT 5;
Copy

集約関数を含むクエリ

集約関数 を含むクエリは、以下の条件をすべて満たす場合にのみプルーニングされます:

  • GROUP BY 句を含む。

  • 最初の ORDER BY 列が GROUP BY 列でもある。

例えば、以下のクエリは、最初の ORDER BY 列である c2 が GROUP BY 列でもあり、集約列ではないので、トップKプルーニングを使用できます:

SELECT c1, c2, c3, COUNT(*) AS agg_col
  FROM mytable
  GROUP BY c1, c2, c3
  ORDER BY c2, c1, agg_col, c3
  LIMIT 5;
Copy

以下のクエリは、最初の ORDER BY 列である agg_col が集約列であるため、top-Kプルーニングを使用できません:

SELECT c1, c2, c3, COUNT(*) AS agg_col
  FROM mytable
  GROUP BY c1, c2, c3
  ORDER BY agg_col, c2, c1
  LIMIT 5;
Copy