Snowflake 查詢最佳化

Snowflake SQL 入門

George Boorman

Senior Curriculum Manager, DataCamp

為何在 Snowflake 最佳化查詢?

  • 更快產生結果
  • 降低成本
    • 縮短查詢時間可減少 CPU 與記憶體等資源用量。

描繪 CPU 與記憶體高用量導致成本上升的圖片

Snowflake SQL 入門

常見查詢問題

  • 爆炸式連接(Exploding Joins):要小心!

錯誤範例

SELECT *
FROM order_details AS od
JOIN pizzas AS p -- Missing ON condition leading to exploding joins

沒有 ON 條件時的查詢列數與時間

Snowflake SQL 入門

常見查詢問題

  • 爆炸式連接(Exploding Joins):要小心!

正確範例

SELECT *
FROM order_details AS od
JOIN pizzas AS p
ON od.pizza_id = p.pizza_id

有 ON 條件時的查詢列數與時間

Snowflake SQL 入門

常見查詢問題

  • UNIONUNION ALL:要分清
    • UNION 會去重,查詢較慢
    • 若無重複時,UNION ALL 較快
  • 大量資料的處理
    • 用篩選縮小資料範圍
    • 使用限制以更快得到結果
Snowflake SQL 入門

如何最佳化查詢?

SELECT * ⌛

SELECT
    *
FROM SNOWFLAKE_SAMPLE_DATA.TPCH_SF100.ORDERS

查詢詳細資訊、時間與列數

SELECT LIMIT 10* ⚡

SELECT *
FROM SNOWFLAKE_SAMPLE_DATA.TPCH_SF100.ORDERS
LIMIT 10

使用 LIMIT 10 的查詢詳細、時間與列數

Snowflake SQL 入門

如何最佳化查詢?

使用 SELECT *

SELECT 
    *
FROM SNOWFLAKE_SAMPLE_DATA.TPCH_SF100.ORDERS

查詢詳細資訊、時間與列數

避免 SELECT *

SELECT o_orderdate, 
    o_orderstatus 
FROM SNOWFLAKE_SAMPLE_DATA.TPCH_SF100.ORDERS

以欄位名稱查詢時的時間與列數

Snowflake SQL 入門

如何最佳化查詢?

盡早篩選

  • 儘早使用 WHERE 子句
  • JOIN 之前先套用篩選
    • JOIN 需處理的列數更少
Snowflake SQL 入門

未提早篩選

SELECT orders.order_id, 
       orders.order_date, 
       pizza_type.name, 
       pizzas.pizza_size
FROM orders
JOIN order_details 
ON orders.order_id = order_details.order_id
JOIN pizzas 
ON order_details.pizza_id = pizzas.pizza_id
JOIN pizza_type 
ON pizzas.pizza_type_id = pizza_type.pizza_type_id
WHERE orders.order_date = '2015-01-01';  -- Filtering after JOIN
Snowflake SQL 入門

已提早篩選

WITH filtered_orders AS (
  SELECT *
  FROM orders
  WHERE order_date = '2015-01-01'  -- Filtering in CTE before JOIN
)
SELECT filtered_orders.order_id, 
       filtered_orders.order_date, 
       pizza_type.name, 
       pizzas.pizza_size
FROM filtered_orders -- Joining with CTE
JOIN order_details
ON filtered_orders.order_id = order_details.order_id
JOIN pizzas
ON order_details.pizza_id = pizzas.pizza_id
JOIN pizza_type
ON pizzas.pizza_type_id = pizza_type.pizza_type_id;
Snowflake SQL 入門

查詢歷史

  • 查詢歷史
    • snowflake.account_usage.query_history
    • 查詢歷史提供多種指標,例如執行時間
SELECT query_text, start_time, end_time, execution_time 
FROM
   snowflake.account_usage.query_history
WHERE query_text ILIKE '%order_details%'

Screenshot 2023-09-01 at 14.32.29.png

  • ILIKE:不分大小寫的字串比對
Snowflake SQL 入門

查詢歷史

  • 找出緩慢或高頻執行的查詢
SELECT query_text, 
    start_time, 
    end_time, 
    execution_time 
FROM
   snowflake.account_usage.query_history
WHERE
   execution_time > 1000

篩選執行時間大於 1000ms 的結果

Snowflake SQL 入門

一起來練習吧!

Snowflake SQL 入門

Preparing Video For Download...