Top-K Pruning für verbesserte Abfrageleistung

Wenn eine SELECT-Anweisung die Klauseln LIMIT und ORDER BY enthält, durchsucht Snowflake normalerweise alle in Frage kommenden Zeilen, da jede Zeile zu den Top-K-Ergebnissen gehören könnte, wobei K der Wert aus der Klausel LIMIT ist. Beim Top-K Pruning stoppt Snowflake die Suche, wenn es feststellt, dass keine der verbleibenden Zeilen in einem Resultset enthalten sein kann, das aus K-Datensätzen besteht.

Top-K Pruning kann die Leistung von SELECT-Anweisungen verbessern, die die Klauseln LIMIT und ORDER BY enthalten. Abfragen über große Tabellen profitieren am meisten vom Top-K Pruning.

Abfragen, die Top-K Pruning verwenden

Snowflake wendet Top-K-Pruning nur an, wenn alle der folgenden Punkte zutreffen:

  • Die Abfrage enthält sowohl eine ORDER BY-Klausel als auch eine LIMIT-Klausel.

  • Die erste in der ORDER BY-Klausel angegebene Spalte hat einen der folgenden Datentypen:

    Wenn mehrere Spalten angegeben werden, berücksichtigt Snowflake nur die erste Spalte.

  • Wenn die Abfrage eine Verknüpfung enthält, ist die Spalte ORDER BY eine Spalte aus der größeren Tabelle. Im Data Warehousing wird die größere Tabelle oft als Faktentabelle oder Sondierungsseite bezeichnet. Die kleinere Tabelle wird als die Dimensionstabelle bezeichnet.

Abfragen mit LIMIT-Klauseln, die bereits schnell sind (z. B. Abfragen, bei denen ein vollständiger Tabellenscan schnell ist), profitieren möglicherweise nicht vom Top-K Pruning. Abfragen, die weniger als K Zeilen zurückgeben, sind ebenfalls nicht von Vorteil.

Abfragen, die ORDER BY. … DESCENDING für ein nullbares Feld enthalten, werden nur dann ausgegrenzt, wenn sie auch NULLS LAST enthalten.

Abfragen auf VARIANT-Spalten

In diesem Abschnitt finden Sie Beispiele für Abfragen auf ein Feld in einer VARIANT-Spalte, um die Arten von Abfragen zu zeigen, die Top-K Pruning verwenden können.

Erstellen Sie eine Tabelle mit einer VARIANT-Spalte, und fügen Sie Daten ein:

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

Diese Tabelle ist relativ klein, um ein Beispiel zu geben, aber denken Sie daran, dass das Top-K Pruning größeren Tabellen zugutekommt.

Die folgenden Abfragen auf diese Tabelle können Top-K Pruning verwenden:

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

Die folgende Abfrage kann das Top-K Pruning nicht verwenden, da der Wert nicht in den zugrunde liegenden Datentyp gecastet wurde:

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

Die folgende Abfrage kann das Top-K Pruning nicht verwenden, da der Wert in einen Datentyp gecastet wurde, der sich vom zugrunde liegenden Datentyp unterscheidet:

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

Abfragen, die eine Aggregatfunktion enthalten

Abfragen, die eine Aggregatfunktion enthalten, werden nur beschnitten, wenn sie alle der folgenden Bedingungen erfüllen:

  • Sie enthalten eine GROUP BY-Klausel.

  • Die erste ORDER BY Spalte ist auch eine GROUP BY Spalte.

Die folgende Abfrage kann zum Beispiel Top-K Pruning verwenden, da die erste ORDER BY Spalte c2 auch eine GROUP BY Spalte ist und keine aggregierte Spalte darstellt:

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

Die folgende Abfrage kann kein Top-K Pruning verwenden, da die erste ORDER BY Spalte agg_col eine aggregierte Spalte ist:

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