Snowflake 查询优化

Snowflake SQL 入门

George Boorman

Senior Curriculum Manager, DataCamp

为何在 Snowflake 中优化查询?

  • 更快得到结果
  • 降低成本
    • 查询更短,占用更少 CPU 和内存

高 CPU 和内存使用导致花费的图示

Snowflake SQL 入门

常见查询问题

  • 爆炸式 JOIN:需谨慎!

错误

SELECT *
FROM order_details AS od
JOIN pizzas AS p -- 缺少 ON 条件,导致爆炸式 JOIN

无 ON 条件时的查询行数和用时

Snowflake SQL 入门

常见查询问题

  • 爆炸式 JOIN:需谨慎!

正确

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

有 ON 条件时的查询行数和用时

Snowflake SQL 入门

常见查询问题

  • UNION vs UNION ALL:区别
    • UNION 去重,较慢
    • 若无重复,UNION ALL 更快
  • 大数据处理
    • 用筛选收窄数据
    • 使用 LIMIT 加速结果
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';  -- 先 JOIN 后过滤
Snowflake SQL 入门

已及早过滤

WITH filtered_orders AS (
  SELECT *
  FROM orders
  WHERE order_date = '2015-01-01'  -- 在 CTE 中先过滤,再 JOIN
)
SELECT filtered_orders.order_id, 
       filtered_orders.order_date, 
       pizza_type.name, 
       pizzas.pizza_size
FROM filtered_orders -- 与 CTE 进行 JOIN
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%'

2023-09-01 14.32.29 的截图

  • 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 入门

¡Vamos a practicar!

Snowflake SQL 入门

Preparing Video For Download...