UNION
和UNION ALL
在某些情況下,使用OR
連接的謂詞可以使查詢性能優於等效查詢。據我所知,這部分是因爲UNION
子查詢可以並行執行,因此他們可以擁有與連接謂詞的每個部分相關的自己的「子計劃」,由於更簡單的適用查詢轉換,該子查詢可能更加優化。讓Oracle將OR連接謂詞轉換爲UNION ALL操作
但是,編寫OR
- 即使將子查詢因子應用於UNION ALL
解決方案,連接謂詞通常也更具可讀性和簡潔性。我的問題是:是否有辦法向Oracle表明,單個昂貴的OR
謂詞應該轉換爲UNION ALL
操作?如果有這樣的提示/方法,在什麼情況下可以應用(例如,謂詞所涉及的列中是否存在任何約束)?舉個例子:
CREATE TABLE a AS
SELECT 1 x, 2 y FROM DUAL UNION ALL
SELECT 2 x, 1 y FROM DUAL;
-- This query...
SELECT * FROM a
WHERE x = 1 OR y = 1
-- Is sometimes outperformed by this one, for more complex table sources...
-- Note: in my case, I can safely apply UNION ALL. I know the two predicates to
-- be mutually exclusive.
SELECT * FROM a
WHERE x = 1
UNION ALL
SELECT * FROM a
WHERE y = 1
注意,我知道了/*+ USE_CONCAT */
暗示:
SELECT /*+ USE_CONCAT */ * FROM a
WHERE x = 1 OR y = 1
但它似乎並沒有產生我需要什麼(在執行計劃中沒有強制UNION ALL
操作):
-------------------------------------------
| Id | Operation | Name | E-Rows |
-------------------------------------------
| 0 | SELECT STATEMENT | | |
|* 1 | TABLE ACCESS FULL| A | 2 |
-------------------------------------------
也許,這個提示有一些限制嗎?我有Oracle 11g2可用於此。
條件'x = 1或y = 1'會返回多少行(以所有行的百分比表示)?在「或」查詢中使用「PARALLEL」提示怎麼辦? –
@a_horse_with_no_name:實際上,(實際)條件是'(flag_function()= 1和condition1)或(flag_function()= 0和condition2)'的形式。這兩個子條件根據PL/SQL'flag_function()'互相排斥。我注意到,在使用'UNION ALL'而不是使用'OR'時,Oracle爲此創建了一個更好的計劃。 'PARALLEL'可能沒有什麼幫助,因爲在這種情況下數據量並不是很大,但是計劃很複雜......此外,這個查詢在用戶會話中運行得非常頻繁。我不想用'PARALLEL'提示 –
來處理太多資源。這些查詢並不等同。你應該使用UNION而不是UNION ALL。如果行和行的x和y都等於1,則會得到不同的結果。 – GriffeyDog