是否有任何 RDBMS 並行化或以其他方式優化 UNION 查詢?
對於具有滿足兩個子查詢的行的範例數據集:
SELECT h.batch, li.id as line_item, d.prusr as price, 0 as advertised FROM schema.lineitem li INNER JOIN schema.detail d on d.line = li.line and d.item = li.item INNER JOIN schema.header h on d.batch = h.batch LEFT JOIN schema.specialoffer sp ON sp.LINE = d.LINE AND sp.ITEM = d.ITEM WHERE h.status = 'T' AND sp.batch IS NULL UNION ALL SELECT h.batch, li.id as line_item, d.prusr as price, 1 as advertised FROM schema.lineitem li INNER JOIN schema.detail d on d.line = li.line and d.item = li.item INNER JOIN schema.header h on d.batch = h.batch INNER JOIN schema.specialoffer sp ON sp.LINE = d.LINE AND sp.ITEM = d.ITEM WHERE h.status = 'T'
什麼 RDBMS 將嘗試並行化這種類型的查詢?我也對您可能知道的任何其他“幕後”優化感興趣,但並行化是這個問題的主要焦點。
我已經找到的參考資料:
- MySQL : 否 - MySQL 可以並行化 UNION 子查詢(或任何東西)嗎?
- Oracle:也許 -數據庫是否並行化包含聯合的 SQL 查詢?
UNION
/每個部分UNION ALL
可以同時執行嗎?甲骨文
是(甲骨文 12c+)
MySQL
否(對於 OP 的問題)
PostgreSQL
對於 Postgres 10 或更早版本,
否 對於Postgres 11是,目前處於測試階段
微軟 SQL 伺服器
大多數情況下no , when
UNION ALL
由Concatenation運算符實現。儘管沒有記錄(或保證),但觀察到串聯總是按順序從其輸入中讀取。可以使用多個執行執行緒來處理每個輸入。可能有一段時間,隨著處理從一個輸入移動到下一個,來自不同實例的執行緒正在從不同的輸入讀取。有點是的,when
UNION ALL
由Concatenation運算符實現並且輸入駐留在不同的伺服器上(Open()
呼叫是非同步執行的 - Async Concat運算符)。期間發生了多少處理Open()
取決於計劃形狀。大多數情況下,當或由Merge Join Concatenation運算符實現時是肯定的,因為每個實例(執行緒)根據需要從任何輸入中讀取以執行保持順序的聯合。
UNION``UNION ALL
還有其他“幕後”類型的優化嗎?
在文獻中發現了幾種關於常見子表達式辨識的方法:在兩個或多個聯合子查詢中檢測相同的表達式。完成後,您可以使用以下等價性:
(A join B join C) union (A join B join D) -> A join B join (C union D)
當您估計此計劃會更便宜時,在連接之前推送聯合,或者使用來自稱為多查詢優化領域的方法(這裡顯然我們有一個查詢,但我們可以將不同的子查詢視為單獨的查詢)以便重用一種表達。同樣,重用表達式的決定並非易事,因為這樣做通常需要實現中間結果,並且可能導致執行時間更短。此外,如果子查詢中存在多個複雜的公共表達式,則決定應具體化哪個(甚至是表達式的哪個子表達式)會影響其餘的決策,從而使優化期間的搜尋空間成倍指數增長. 無論如何,檢查這些問題會嚴重影響優化時間,雖然有很有前途的研究原型,但我相信大多數商業產品都不會考慮這種優化。另請注意,使用此類方法會導致整個查詢“並行性降低”,因為您不能再完全獨立地執行每個子查詢。