2011-08-24 33 views
2

我已經用一個完整的例子來跟蹤這個問題,以防它不清楚我的意思。SQL Server是否在複雜視圖中傳播WHERE條件?

我已經制作了一個視圖,它從大約五張表中加入數據。這些表包含大量數據,查詢運行緩慢。我的問題是,如果我做的:

SELECT * FROM myView WHERE PersonID = 1000 

沒有SQL服務器「知道我的意思」,並自動傳播該條件的視圖的基礎加入?所以它不會爲大家運行,但會在正確的階段最小化結果集。或者它會運行一切,然後在整個結果集上執行WHERE ID = 1000


爲例

爲了簡化(...希望)我的意思,這裏是一個例子僞TSQL場景:

TABLE People (
    ID, 
    Surname, 
    DOB 
) 
TABLE Activities (
    ID, 
    TypeID, 
    LocationID, 
    Date 
) 
TABLE PersonActivityInvolvements (
    ID, 
    PersonID, 
    ActivityID 
) 
TABLE ActivityTypes (
    ID, 
    Name 
) 
TABLE Locations (
    ID, 
    Street, 
    City 
) 

所以我想一個視圖,顯示了我所有People,他們參與了任何ActivitiesActivityTypeLocation它發生。雖然這個設置並不是非常複雜,但是如果每個實體都有數以萬計的話,可能需要很長時間才能執行。

的觀點可能是這樣的:

SELECT 
    * 
FROM 
    People LEFT OUTER JOIN PersonActivityInvolvement PA 
    ON People.ID = PA.ID 
     INNER JOIN Activity 
     ON PA.ID = Activity.ID 
      INNER JOIN ActivityTypes AT 
      ON A.TypeID = AT.ID 
       INNER JOIN Locations 
       ON A.LocationID = Locations.ID 

所以,如果是做

SELECT * FROM myView WHERE DOB >= dateAdd(YEAR, -18, getDate()) 

會查看運行中的查詢爲大家或將SQL服務器知道它應該應用它到People.DOB字段?

+3

這很容易使用SQL Server查詢分析器進行測試。顯示執行計劃並查看應用於表的過濾器。如果它顯示應用的地點條件,那麼它是可傳遞的。 –

回答

1

發動機將做任何它認爲是最快的。如果您將該字段編入索引,並且您的所有密鑰都已建立索引,則它可能首先運行或不運行該過濾器。

如果WHERE子句更昂貴(即無索引),它可能實際上運行過濾器最後 - 這樣昂貴的操作運行在最小的結果集上。

只有這樣才能知道運行查詢並檢查執行計劃(ACTUAL未估計)。

2

這就是所謂的謂詞推。

儘管存在一些存在問題的構造(例如,請參閱this article的最後部分),但SQL Server通常很擅長。

檢查執行計劃以查看謂詞的應用位置。

3

通常,優化程序將用aplomb處理此問題,但隨着查詢和隱含子查詢變得越來越複雜,優化程序將選擇正確執行路徑的機會相應減少。這可以通過在表上有更多的索引或者將要檢查的表上非常相似的索引來加劇。

作爲一般規則,我試圖阻止加入視圖,並且我強烈建議不要創建由其他視圖組成的視圖。