2

我使用SQL Server 2008,但可以使用更高版本。在表值函數中混合索引字段和計算字段

我有兩張關於一些人的數據非常相似,但格式不同(這兩組人之間沒有交集)的表格。

Table 1:  
int personID  
bit IsOldPerson //this field is indexed 

Table 2: 
int PersonID 
int Age 

我想有具有相同的結構表1。所以我寫了下面的腳本(簡化版本)的組合視圖:

CREATE FUNCTION CombinedView(@date date) 
RETURNS TABLE 
AS 
RETURN   
    select personID as PID, IsOldPerson as IOP 
    from Table1 

    union all 

    select personID as PID, dbo.CheckIfOld(Age,@date) as IOP 
    from Table2 
GO 

功能「CheckIfOld」返回的是yes /否取決於@date日期的輸入年齡。

所以我有2個問題在這裏:

A.如果我嘗試select * from CombinedView(TODAY) where IOP=true時,SQL Server是否會做下列分別:該字段IsOldPerson 1)表1使用索引,做一個「聰明「基於指標的結果選擇; 2)對於表2,計算所有行的CheckIfOld,並在計算過程中逐行選取或拒絕行?

B.如何在這個特殊情況下檢查執行計劃以瞭解我在問題(A)中的猜測是否正確?

任何幫助,非常感謝!謝謝!

+0

你的猜測看起來很準確我。假設'Table1(IsOldPerson)INCLUDE(personID)'上的覆蓋索引我期望計劃顯示一個串聯運算符,並在table1上顯示一個索引查找,並在table2上顯示一個帶有過濾器的掃描。請參閱[如何獲取查詢執行計劃?](http://stackoverflow.com/questions/7359702/how-do-i-obtain-a-query-execution-plan/7359705#7359705) –

+0

@Martin Smith:非常感謝評論!對不起,我只是意識到我必須修改問題的性質,並使用相當表值函數而不是視圖。 – user2925546

+0

雖然現在你已經將它編輯爲一個函數而不是一個視圖,但這取決於它是內聯TVF還是多視圖TVF。您所顯示的功能無效,因爲它既不是。 –

回答

0

是的,如果查詢不是太複雜,查詢優化器應該將視圖「透視」到其構成的UNION-ed SELECT語句中,分別評估它們並連接結果。如果Table1上有一個索引,它應該能夠使用它。我使用我們擁有的表格以及您提供的相同功能概念對此進行了測試。我查看了原始SELECT到Table1的查詢計劃,並使用UNION將查詢計劃的SELECT與內聯表值函數進行了比較,查詢計劃中與Table1相關的部分也是相同的 - 並且它使用了索引。

現在,如果性能是一個問題,我建議你做的兩件事情之一:

  1. 若(a)表2是隻讀的重,而不是寫爲重,(b)您有空間,和(c)你可以把CheckIfOld寫成一個單一的CASE語句(因爲它在你的問題中的名字和上下文暗示),那麼你應該考慮在Table2中用IsOldPerson計算並應用一個索引來創建一個持久計算的字段。

  2. 如果表2寫入重量較大,或者您沒有空間存放其他字段,則至少應考慮將CheckIfOld轉換爲內聯函數。取決於它的使用方式,您可能會獲得性能提升。在你的情況下,它會使用這樣的:

    選擇PERSONID作爲PID,IOP.IsOldPerson從表2 CROSS APPLY dbo.CheckIfOld(年齡,@日期)AS IOP