本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
優化巴貝魚中的相關子查詢
相關子查詢從外部查詢引用表列。它是由外部查詢返回的每一行評估一次。在下列範例中,子查詢會參考資料表 t1 中的資料行。此資料表不包含在子查詢的子FROM句中,但會在外部查詢的子FROM句中參考。如果表 t1 有 100 萬行,則子查詢需要評估 100 萬次。
SELECT col1, col2 FROM t1 WHERE col1 < (SELECT sum(col1) FROM t2 WHERE t1.col2 = t2.col2);
使用子查詢轉換提高巴貝爾魚查詢性能
Babelfish 可以通過將它們轉換為等效的外部連接來加速相關的子查詢。此最佳化適用於下列兩種類型的相關子查詢:
-
傳回單一彙總值並顯示在SELECT清單中的子查詢。如需詳細資訊,請參閱 Microsoft 交易SQL文件中的SELECT子句
。 SELECT ( SELECT avg(a) FROM inner_sb_t2 WHERE inner_sb_t2.a = outer_sb_t1.a) FROM outer_sb_t1;
-
傳回單一彙總值並出現在子WHERE句中的子查詢。
SELECT * FROM outer_sb_t1 WHERE ( SELECT avg(a) FROM inner_sb_t2 WHERE inner_sb_t2.a = outer_sb_t1.a) > 1.0;
在子查詢中啟用轉換
若要啟用相互關聯的子查詢轉換為對等的外部聯結,請將apg_enable_correlated_scalar_transform
參數設定為。ON
此參數在巴貝爾魚 4.2.0 及更高版本中提供。此參數的預設值為 OFF
。
您可以修改叢集或執行處理參數群組來設定參數。如需進一步了解,請參閱 Amazon Aurora 的參數組 RDS。
或者,您可以通過調用該函數來僅配置當前會話的設置set_config
。例如,執行下列命令以開啟 Babelfish 中的子查詢快取。若要深入瞭解,請參閱組態設定功能
1> SELECT set_config('apg_enable_subquery_cache', 'on', false) 2> GO
驗證轉換
使用命EXPLAIN令來驗證相關的子查詢是否已轉換為查詢計畫中的外部聯結。如需詳細資訊,請參閱使用解釋計劃改善 Babelfish 查詢效能。
啟用轉換後,適用的相關子查詢部分將被轉換為外部連接。例如:
1>
select set_config('apg_enable_correlated_scalar_transform', 'true', false);2>
GO1>
set BABELFISH_STATISTICS PROFILE on2>
GO1>
select customer_name, ( select max(o.cost) from correlated_orders o2>
where o.customer_id = c.customer_id and o.total_amount > 10 and o.customer_id != 10) AS max_order_amount3>
from correlated_customers c order by customer_name ;4>
GOQUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Query Text: select customer_name, ( select max(o.cost) from correlated_orders o where o.customer_id = c.customer_id and o.total_amount > 10 and o.customer_id != 10 ) AS max_order_amount from correlated_customers c order by customer_name Sort (cost=88.23..90.18 rows=780 width=40) Sort Key: c.customer_name NULLS FIRST -> Hash Left Join (cost=30.90..50.76 rows=780 width=40) Hash Cond: (c.customer_id = o.customer_id) -> Seq Scan on correlated_customers c (cost=0.00..17.80 rows=780 width=36) -> Hash (cost=28.73..28.73 rows=174 width=12) -> HashAggregate (cost=26.99..28.73 rows=174 width=12) Group Key: o.customer_id -> Seq Scan on correlated_orders o (cost=0.00..25.30 rows=338 width=12) Filter: (((total_amount)::numeric > 10) AND (customer_id <> 10)) ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
當GUC參數轉動時,不會轉換相同的查詢OFF
。計劃不會有外部聯結,而是子計劃。
1>
select set_config('apg_enable_correlated_scalar_transform', 'false', false);2>
GO1>
select customer_name, ( select max(o.cost)2>
from correlated_orders o3>
where o.customer_id = c.customer_id and o.total_amount > 10 and o.customer_id != 10) AS max_order_amount4>
from correlated_customers c order by customer_name ;5>
GOQUERY PLAN ------------------------------------------------------------------------------------------------------------------------- Sort (cost=21789.97..21791.92 rows=780 width=40) Sort Key: c.customer_name NULLS FIRST -> Seq Scan on correlated_customers c (cost=0.00..21752.50 rows=780 width=40) SubPlan 1 -> Aggregate (cost=27.86..27.87 rows=1 width=8) -> Seq Scan on correlated_orders o (cost=0.00..27.85 rows=2 width=8) Filter: (((total_amount)::numeric > 10) AND (customer_id <> 10) AND (customer_id = c.customer_id))
限制
-
子查詢必須在 select_list 中或其中一個條件中。否則,它將不會被轉換。
-
子查詢必須返回一個聚合函數。轉換不支援使用者定義的彙總函式。
-
返回表達式不是簡單聚合函數的子查詢將不會被轉換。
-
子查詢子句中的相關WHERE條件應該是一個簡單的列引用。否則,它將不會被轉換。
子查詢中的相關條件 where 子句必須是一個普通的相等謂詞。
包含子TOP句的相關子查詢無法轉換。
-
子查詢不能包含HAVING或 GROUP BY 子句。
-
子查詢中的 where 子句可能包含一個或多個謂詞結合在一起。AND如果子WHERE句包含 OR 子句,則無法轉換。