Sql-Server

是否有任何 RDBMS 並行化或以其他方式優化 UNION 查詢?

  • September 6, 2018

對於具有滿足兩個子查詢的行的範例數據集:

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 將嘗試並行化這種類型的查詢?我也對您可能知道的任何其他“幕後”優化感興趣,但並行化是這個問題的主要焦點。

我已經找到的參考資料:

UNION/每個部分UNION ALL可以同時執行嗎?

甲骨文

是(甲骨文 12c+

MySQL

否(對於 OP 的問題

PostgreSQL

對於 Postgres 10 或更早版本,

否 對於Postgres 11是,目前處於測試階段

微軟 SQL 伺服器

大多數情況下no , whenUNION ALLConcatenation運算符實現。儘管沒有記錄(或保證),但觀察到串聯總是按順序從其輸入中讀取。可以使用多個執行執行緒來處理每個輸入。可能有一段時間,隨著處理從一個輸入移動到下一個,來自不同實例的執行緒正在從不同的輸入讀取。

有點的,whenUNION ALLConcatenation運算符實現並且輸入駐留在不同的伺服器上(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)當您估計此計劃會更便宜時,在連接之前推送聯合,或者使用來自稱為多查詢優化領域的方法(這裡顯然我們有一個查詢,但我們可以將不同的子查詢視為單獨的查詢)以便重用一種表達。同樣,重用表達式的決定並非易事,因為這樣做通常需要實現中間結果,並且可能導致執行時間更短。此外,如果子查詢中存在多個複雜的公共表達式,則決定應具體化哪個(甚至是表達式的哪個子表達式)會影響其餘的決策,從而使優化期間的搜尋空間成倍指數增長. 無論如何,檢查這些問題會嚴重影響優化時間,雖然有很有前途的研究原型,但我相信大多數商業產品都不會考慮這種優化。另請注意,使用此類方法會導致整個查詢“並行性降低”,因為您不能再完全獨立地執行每個子查詢。

引用自:https://dba.stackexchange.com/questions/216818