本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
設計 Amazon Redshift 查詢的最佳實務
本節提供設計查詢的最佳實務概觀。我們建議您遵循本節中的最佳實務,以獲得最佳查詢效能和效率。
避免使用 SELECT * FROM 陳述式
建議您避免使用 SELECT * FROM
陳述式。反之,一律列出要分析的資料欄。這可減少查詢執行時間,並掃描 Amazon Redshift Spectrum 查詢的成本。
要避免的內容範例
select * from sales;
最佳實務範例
select sales_date, sales_amt from sales;
識別查詢問題
建議您檢查 STL_ALERT_EVENT_LOG 檢視,以識別和修正查詢的可能問題。
取得查詢的摘要資訊
我們建議您使用 SVL_QUERY_SUMMARY 和 SVL_QUERY_REPORT 檢視來取得查詢的摘要資訊。您可以使用此資訊來最佳化查詢。
避免跨聯結
除非絕對必要,否則建議您避免使用跨聯結。如果沒有聯結條件,跨聯結會產生兩個資料表的笛卡爾產品。跨聯結通常會以巢狀迴圈聯結 (可能的聯結類型中速度最慢) 的方式執行。
要避免的內容範例
select c.c_name, n.n_name from tpch.customer c, tpch.nation n;
最佳實務範例
select c.c_name, n.n_name from tpch.customer c, join tpch.nation n on n.n_nationkey = c.c_nationkey;
避免查詢述詞中的函數
建議您避免在查詢述詞中使用 函數。在查詢述詞中使用函數可能會對效能產生負面影響,因為函數通常會為每個資料列增加額外的處理開銷,並減慢查詢的整體執行速度。
要避免的內容範例
select sum(o_totalprice) from tpch.orders where datepart(year, o_orderdate) = 1992;
最佳實務範例
select sum(o_totalprice) from tpch.orders where o_orderdate between '1992-01-01' and '1992-12-31';
避免不必要的投射轉換
我們建議您避免在查詢上使用不必要的轉換,因為轉換資料類型需要時間和資源,並減緩查詢執行速度。
要避免的內容範例
select sum(o_totalprice) from tpch.orders where o_ordertime::date = '1992-01-01';
最佳實務範例
select sum(o_totalprice) from tpch.orders where o_ordertime between '1992-01-01 00:00:00' and '1992-12-31 23:59:59';
使用 CASE 表達式進行複雜的彙總
我們建議您使用 CASE 表達式來執行複雜的彙總,而不是多次從相同的資料表中選取 。
要避免的內容範例
select sum(sales_amt) as us_sales from sales where country = 'US'; select sum(sales_amt) as ca_sales from sales where country = 'CA';
最佳實務範例
select sum(case when country = 'US' then sales_amt end) as us_sales, sum(case when country = 'CA' then sales_amt end) as ca_sales from sales;
使用子查詢
如果查詢中的一個資料表僅用於述詞條件,且子查詢傳回少量資料列 (少於約 200),建議您使用子查詢。
要避免的內容範例
如果子查詢傳回少於 200 列:
select sum(order_amt) as total_sales from sales where region_key IN (select region_key from regions where state = 'CA');
最佳實務範例
如果子查詢傳回大於或等於 200 列:
select sum(o.order_amt) as total_sales from sales o join regions r on r.region_key = o.region_key and r.state = 'CA';
使用述詞
我們建議您使用述詞來盡可能限制資料集。SQL 中使用述詞來篩選和限制查詢中傳回的資料。透過在述詞中指定條件,您可以根據指定的條件指定查詢結果中必須包含哪些資料列。這可讓您僅擷取您感興趣的資料,並改善查詢的效率和準確性。如需詳細資訊,請參閱《Amazon Redshift 文件》中的條件。
新增述詞以使用聯結篩選資料表
我們建議您新增述詞來篩選參與聯結的資料表,即使述詞套用相同的篩選條件。使用述詞篩選具有 SQL 聯結的資料表,可透過減少必須處理的資料量,以及減少中繼結果集的大小,來改善查詢效能。透過在 WHERE
子句中指定聯結操作的條件,查詢執行引擎可以在聯結前消除不符合條件的資料列。這會產生較小的結果集,並加快查詢執行速度。
要避免的內容範例
select p.product_name, sum(o.order_amt) from sales o join product p on r.product_key = o.product_key where o.order_date > '2022-01-01';
最佳實務範例
select p.product_name, sum(o.order_amt) from sales o join product p on p.product_key = o.product_key and p.added_date > '2022-01-01' where o.order_date > '2022-01-01';
針對述詞使用最便宜的運算子
在述詞中,使用您可以花費最低的運算子。比較條件運算子偏好 LIKE 運算子。LIKE
運算子仍偏好 SIMILAR TO 或 POSIX 運算子。
在 GROUP BY 子句中使用排序索引鍵
在 GROUP BY
子句中使用排序索引鍵,讓查詢規劃器可以使用更有效率的彙總。當查詢的GROUP BY
清單僅包含排序索引鍵資料欄時,查詢可能符合單階段彙總的資格,其中一個也是分佈索引鍵。GROUP BY
清單中的排序索引鍵資料欄必須包含第一個排序索引鍵,後面接著您要依排序索引鍵順序使用的其他排序索引鍵。
利用具體化視觀表
如果可能,請將複雜程式碼取代為具體化檢視來重寫查詢,這將大幅改善查詢的效能。如需詳細資訊,請參閱《Amazon Redshift 文件》中的在 Amazon Redshift 中建立具體化視觀表。
請留意 GROUP BY 和 ORDER BY 子句中的資料欄
如果您同時使用 GROUP BY
和 ORDER BY
子句,請確定您在 GROUP BY
和 ORDER BY
子句中以相同的順序放置資料欄。 GROUP BY
隱含地需要對資料進行排序。如果您的ORDER BY
子句不同,則必須對資料進行兩次排序。
要避免的內容範例
select a, b, c, sum(d) from a_table group by b, c, a order by a, b, c
最佳實務範例
select a, b, c, sum(d) from a_table group by a, b, c order by a, b, c