2017-09-02 68 views
0

使用SQL Server數據庫,我有一些SQL代碼試圖從聯合表中獲取並且工作正常。SQL Server查詢長時間聯合使用和列查看

新的要求是將列添加到從視圖讀取的現有SQL語句。我運行了單獨的SQL語句,添加新列後它們運行良好,並且聊天的時間比原始時間稍長。

現在試圖運行所有的SQL語句與聯合在一起,它永遠在運行。

select 
    col 1, col 2, col3, 
    case 
     when 'ee' = (select col 5 from view1 where X.id = id) 
      then 'xx' 
      else 'yy' 
    end as newcol1 
from 
    X, Y, Z 
where 
    condn 1 and condn 2 

union 

select 
    col 1, col 2, col3, 
    case 
     when 'ee' = (select col 5 from view1 where X.id = id) 
      then 'xx' 
      else 'yy' 
    end as newcol1 
from 
    X, Y, Z 
where 
    condn 3 and condn 4 

union 

select 
    col 1, col 2, col3, 
    case 
     when 'ee' = (select col 5 from view1 where X.id = id) 
      then 'xx' 
      else 'yy' 
    end as newcol1 
from 
    X, Y, Z 
where 
    condn 5 and condn 6 

有關優化此查詢的任何建議嗎?

+3

這不是一個查詢......這是僞代碼......「來自X,Y,Z」是ansi 89語法的3路笛卡爾乘積。這本身應該表現糟糕。最重要的是,相關的子查詢「(來自view1的SELECT Col 5 ...」將對外部查詢中的每一行執行一次......然後......你正在做3次.. 。而頂尖的櫻桃是你使用UNION而不是UNION ALL的意思,這意味着你已經在混合中增加了一個獨特的操作。你可能在這裏有一個完美的風暴。 –

+1

[踢壞的習慣:用舊的 - 樣式聯接](http://sqlblog.com/blogs/aaron_bertrand/archive/2009/10/08/bad-habits-to-kick-using-old-style-joins.aspx) - 舊式*逗號在ANSI - ** 92 ** SQL標準(** 25年**之前)中,表*樣式的分離列表被替換爲* proper * ANSI'JOIN'語法,並且不鼓勵使用它 –

+0

感謝您的回覆。將更改爲使用連接,如何更改newcol1以更好地執行使用上述我能夠得到我需要的結果,但它的性能很差,請提供一個例子作爲vladatr。 – user3761541

回答

1

很多人忽視的一件事是,UNION不僅僅會返回所有子查詢行的聯合,但它會檢查重複項,所以它可能會減慢查詢速度。如果要返回三個子查詢的所有結果(包括重複項),則應使用通常速度更快的UNION ALL

例如,假設你得到這些結果來自單個子查詢:使用UNION

Query 1 Query 2 Query 3 
------- ------- ------- 
1, 1, 1 1, 1, 1 4, 5, 6 
2, 2, 2 3, 3, 3 7, 8, 9 
1, 2, 3 3, 2, 1 1, 2, 3 
3, 2, 1    3, 2, 1 

您將獲得:

1, 1, 1 
2, 2, 2 
1, 2, 3 
3, 2, 1 
3, 3, 3 
4, 5, 6 
7, 8, 9 

,並使用UNION ALL您將獲得:

1, 1, 1 
2, 2, 2 
1, 2, 3 
3, 2, 1 
1, 1, 1 
3, 3, 3 
3, 2, 1 
4, 5, 6 
7, 8, 9 
1, 2, 3 
3, 2, 1 

如果你真的需要查詢返回只有區別ct行,您可能需要在查詢返回的列上添加索引,也許他們當前的查詢依賴於由SQL Server創建的自動索引,並且這些更改使優化程序停止使用它們。

1

我建議重寫整個查詢:

SELECT col 1, col 2, col3, 
    case 
     when v.col5 = 'ee' 
      then 'xx' 
      else 'yy' end as newcol1 
FROM X 
INNER JOIN Y ON Y.??? = X.??? 
INNER JOIN Z ON Z.??? = X.??? 
LEFT OUTER JOIN view1 v ON v.id = X.id AND col5 = 'ee' 
WHERE (condn 1 and condn 2) 
    OR (condn 3 and condn 3) 
    OR (condn 5 and condn 6) 

這樣的表X,Y,Z需要只能讀取一次。