設計查詢的 Amazon Redshift 最佳實務 - Amazon Redshift

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

設計查詢的 Amazon Redshift 最佳實務

為達到最大的查詢效能,在建立查詢時,請遵循這些建議:

  • 依據最佳實務設計資料表,為查詢效能提供穩固的基礎。如需詳細資訊,請參閱 設計資料表的 Amazon Redshift 最佳實務

  • 避免使用 select *。僅包含您實際需要的欄位。

  • 使用 CASE 條件式運算式 執行複雜的彙總,而非從相同的資料表多次選取。

  • 除非絕對必要,否則請勿使用交叉聯結。沒有聯結條件的這些聯結,會導致兩個資料表的笛卡兒乘積。交叉聯結通常會執行為巢狀迴圈聯結,這是可能的聯結類型中最慢的。

  • 如果查詢中的一個資料表僅用於述詞條件,而且子查詢返回少量資料列 (小於約 200),則使用子查詢。下列範例使用子查詢以避免聯結 LISTING 資料表。

    select sum(sales.qtysold) from sales where salesid in (select listid from listing where listtime > '2008-12-26');
  • 使用述詞以盡可能限制資料集。

  • 在述詞中,使用最便宜的運算子。比較條件 運算子比 LIKE 運算子好。LIKE 運算子仍比 SIMILAR TOPOSIX 運算子 好。

  • 避免在查詢述詞中使用函式。使用函式需要大量資料列以解析查詢的中間步驟,因此會提高查詢成本。

  • 如有可能,使用 WHERE 子句以限制資料集。接著,查詢規劃器可使用資料列順序,協助判斷哪些記錄符合條件,以跳過掃描大量的磁碟區塊。如果不使用它,查詢執行引擎必須完整掃描參與的欄位。

  • 新增述詞以篩選參與聯結的資料表,即使這些述詞套用相同的篩選條件。查詢會傳回相同的結果集,但 Amazon Redshift 可在掃描步驟之前篩選聯結資料表,並有效地跳過掃描這些資料表的區塊。如果您在用於聯結條件的欄位上進行篩選,就不需要備援篩選條件。

    例如,假設您要聯結 SALESLISTING 以搜尋 12 月之後列出之門票的門票銷售,依照銷售者分組。這兩個資料表皆以日期排序。以下查詢聯結資料表上的共同索引鍵,並篩選大於 12 月 1 日的 listing.listtime 值。

    select listing.sellerid, sum(sales.qtysold) from sales, listing where sales.salesid = listing.listid and listing.listtime > '2008-12-01' group by 1 order by 1;

    WHERE 子句不包含 sales.saletime 的述詞,因此執行引擎被迫掃描整個 SALES 資料表。如果您知道篩選條件會導致較少的資料列參與聯結,那麼也請加入該篩選條件。下列範例大幅縮短執行時間。

    select listing.sellerid, sum(sales.qtysold) from sales, listing where sales.salesid = listing.listid and listing.listtime > '2008-12-01' and sales.saletime > '2008-12-01' group by 1 order by 1;
  • 在 GROUP BY 子句中使用排序索引鍵,讓查詢規劃器可以使用更有效率的彙總。當查詢的 GROUP BY 列表僅包含排序索引鍵欄位,而且其中一欄也是分佈索引鍵,則該查詢可能有資格進行單一階段彙總。GROUP BY 列表中的排序索引鍵欄位必須包含第一個排序索引鍵,然後是您要依照排序索引鍵順序使用的其他排序索引鍵。例如,使用第一個排序索引鍵、第一和第二個排序索引鍵,第一、二和第三個排序索引鍵等等,都是有效的。使用第一和第三個排序索引鍵是無效的。

    您可以執行 EXPLAIN 命令並在查詢的彙總步驟尋找 XN GroupAggregate,以確認使用單一階段彙總。

  • 如果您同時使用 GROUP BY 與 ORDER BY 子句,請確定兩個欄位的順序是相同的。亦即,使用以下方法。

    group by a, b, c order by a, b, c

    請勿使用以下方法。

    group by b, c, a order by a, b, c