Trên warehouse cloud, thời gian và chi phí tỉ lệ với lượng dữ liệu phải quét: BigQuery on-demand tính tiền thẳng theo byte quét, Snowflake và Redshift tính theo thời gian compute, mà quét nhiều thì chạy lâu. Hướng chính là quét ít hơn, không phải thêm index như database OLTP.
Theo thứ tự nên thử:
- Chỉ chọn cột cần. Warehouse lưu theo cột, SELECT * trên bảng 80 cột nghĩa là đọc cả 80 cột.
- Partition theo cột thời gian và luôn lọc trên cột đó để engine bỏ qua các partition không liên quan (partition pruning). Biến đổi cột partition trong điều kiện lọc, như EXTRACT(MONTH FROM order_ts) = 9 hay order_ts + INTERVAL 1 DAY > ..., làm engine không pruning được; để cột partition đứng riêng một vế so sánh. Snowflake không cho tự khai báo partition mà tự chia micro-partition, nên ở đó dùng clustering key.
- Cluster/sort key theo cột hay lọc hoặc join (customer_id, region) để trong mỗi partition engine đọc ít khối hơn.
- Giảm dữ liệu trước khi join: lọc và gộp nhóm bảng lớn trước, rồi mới join với dimension.
- Bảng tổng hợp sẵn hoặc materialized view cho dashboard chạy lặp lại mỗi ngày, thay vì tính lại từ bảng chi tiết mỗi lần mở.
CREATE TABLE sales.fact_orders
PARTITION BY DATE(order_ts)
CLUSTER BY customer_id
AS SELECT * FROM staging.orders;Để biết nên sửa ở đâu, xem query plan và số byte quét (BigQuery hiện ngay trước khi chạy; Snowflake có Query Profile) thay vì đoán.
Lưu ý: partition quá nhỏ (theo giờ trên bảng ít dữ liệu) sinh ra rất nhiều partition nhỏ và chậm hơn. Có thể đặt require_partition_filter trên BigQuery để chặn query quên lọc theo ngày quét cả bảng.