2013-04-22 50 views
1

我在觀看效果時遇到了一些麻煩。特別是一些昂貴的連接,當他們不需要的時候執行。我設法將問題簡化爲最簡單的情況,並使用AdventureWorks示例數據庫創建了以下視圖,該視圖將人員姓名和電子郵件地址組合在一起。是否可以建立一個sql視圖,以便任何連接只在需要時執行?

create view PersonDetails_View 
as 
select P.FirstName, P.LastName, A.EmailAddress 
from Person.Person P 
left outer join Person.EmailAddress A 
    ON P.BusinessEntityID = A.BusinessEntityID 

如果我運行鍼對此視圖以下查詢:

select FirstName from PersonDetails_View 

所生成的查詢等於的:

select P.FirstName 
from Person.Person P 
left outer join Person.EmailAddress A 
    ON P.BusinessEntityID = A.BusinessEntityID 

在這個查詢中有一個不必要的加入正在執行。我知道它爲什麼會發生 - 如果每Person行有多個EmailAddress條目,結果將會不同。然而在這種特殊情況下,映射是1-1,並且總是會是。有沒有辦法阻止這種連接發生,以便生成的查詢等於以下內容?

select P.FirstName 
from Person.Person P 

(這個簡單的例子看起來像微型的優化,但我已經正確成型,並確定不必要的視圖在我的處境中的性能問題加入 - !我保證)

+0

也許你應該使用(從人表,而不是從persondetails_view)的最新查詢人的數據呢?我會在這種情況下使用persondetails_view作爲無用的;) – Arvo 2013-04-22 09:51:03

+0

再次,我把這個分解成了我能做到的最簡單的例子。我覺得發佈一個大型sql視圖,每次加入10個表格的數量對於這個問題來說是不必要的複雜的。 – John 2013-04-22 09:54:22

回答

1

CREATE UNIQUE INDEX ix 
    ON Person.EmailAddress(BusinessEntityID) 

爲了保證不會有多個匹配。這改變了計劃。

以前

enter image description here

enter image description here

+0

謝謝,這工作完美。對於後續操作,如果EmailAddress確實有多個匹配項,但是您以某種方式執行了查詢(無關緊要)(例如,從PersonDetails_View中選擇不同的FirstName),是否會有類似的解決方案? – John 2013-04-22 10:10:16

+1

@John - 看起來像創建視圖PersonDetails_View作爲選擇P.FirstName,P.LastName,A.EmailAddress從Person.Person P左外連接(選擇最大(EmailAddress)作爲EmailAddress,BusinessEntityID從Person.EmailAddress組由BusinessEntityID)A ON P.BusinessEntityID = A.BusinessEntityID'做了簡化,但是'SELECT'中包含'EmailAddress'的計劃更加複雜。 – 2013-04-22 10:24:05

+0

再次感謝那個。這似乎做了簡化,但確實使查詢更復雜。我將不得不介紹一些,看看哪個選項最適合我。 – John 2013-04-22 10:33:30

0

可以使這一觀點作爲索引視圖。然後它會提高性能,而且每次從視圖中獲取數據時都不會加入。

由於索引視圖爲連接查詢的結果集創建一個單獨的物理存儲器,一次訪問此視圖時,它將與從單個表中訪問相同。

+0

視圖引用的基礎表被更新頻繁,索引視圖可能會更糟糕。 – John 2013-04-22 09:52:31

相關問題