2010-07-11 77 views
3

當我查詢與一個查詢相對的視圖時,Mssql會更快嗎?查詢視圖比查詢慢嗎?

例如

當我有這樣的觀點:

create view ViewInvoicesWithCustomersName 
Select * from Invoices left join Customer on Customer.ID=Invoices.CustomerID 

什麼會更快還是會甚至快?

a) select * from ViewInvoicesWithCustomersName where customerName="Bart" 
b) select * from Invoices left join Customer on Customer.ID=Invoices.CustomerID 
    where customername="Bart" 

回答

4

雖然在你的簡單示例中事情將是一樣的使用嵌套視圖時需要謹慎。

我在一個系統上工作,在這個系統上,在大約6級嵌套視圖上建立了30秒後,查詢超時,並且通過重寫基本表的查詢,設法加快了約100倍。

下面是一個可能出現的問題類型的簡單示例。

CREATE VIEW MaxTypes 
AS 
SELECT 
    [number], 
    MAX(type) AS MaxType 
    FROM [master].[dbo].[spt_values] 
GROUP BY [number] 

GO 

CREATE VIEW MinTypes 
AS 
SELECT 
    [number], 
    MIN(type) AS MinType 
    FROM [master].[dbo].[spt_values] 
GROUP BY [number] 

GO 
SET STATISTICS IO ON 

SELECT  MaxTypes.number, MinTypes.MinType, MaxTypes.MaxType 
FROM   MinTypes INNER JOIN 
         MaxTypes ON MinTypes.number = MaxTypes.number 
ORDER BY MaxTypes.number 

/* 
Gives 

Table 'spt_values'. Scan count 2, logical reads 16, physical reads 0, 
read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. 
*/ 
GO 

SELECT 
    [number], 
    MAX(type) AS MaxType, 
    MIN(type) AS MinType 
    FROM [master].[dbo].[spt_values] 
GROUP BY [number] 
ORDER BY [number] 

/* 
Gives 

Table 'spt_values'. Scan count 1, logical reads 8, physical reads 0, 
read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. 
*/ 

enter image description here

+0

+1雖然其他答案對於所發佈的具體示例是正確的,但在一般情況下,您的答案是正確的,即取決於查詢!物化的VIEW也值得一提。 – onedaywhen 2010-07-12 09:08:37

+0

那麼我們假設經驗法則是您不創建視圖視圖? – MichaelD 2010-07-16 14:31:20

+0

@MichaelD - 我認爲經驗法則應該是,當處理嵌套視圖時,檢查執行計劃並驗證視圖的使用不會引入額外的不必要的操作符(特別是如果您有意見加入視圖) – 2010-07-16 14:39:57

2

這兩個查詢都是等效的。

2

他們是一樣的,但查看執行計劃,以便您可以看到發生了什麼。如果您遇到性能問題,則可能需要索引。假定Customer.ID是具有聚集索引的主鍵,則Invoice.CustomerIDCustomerName是索引的良好候選者。

3

視圖是一個簡單的擴展/未放入主查詢的宏。所以這些是相同的。

注意:如果customername位於Customer表中,則實際上已創建了INNER JOIN。爲了過濾Bart的發票發票沒有客戶你需要這樣做:

select 
    * 
from 
    Invoices 
    left join 
    Customer on Customer.ID=Invoices.CustomerID and customername="Bart" 
+0

該查詢顯示所有發票和唯一的Barts發票將顯示客戶名稱。而不僅僅是沒有客戶的barts發票和發票。 雖然你對內聯接是正確的,但它必須是內聯接。 – MichaelD 2010-07-11 10:45:32

2

雙方應採取幾乎相同的時間。

查看此處僅查看訪問視圖時爲數據執行的查詢。

還有另一種類型的視圖,即物化視圖。這種類型的視圖具有物理存在性,如表格。並且查詢(在視圖創建期間傳遞)在訪問這種類型的視圖時不被執行。從這種類型的視圖獲取應該更快。

+0

有趣,但似乎有物化觀點。基礎表的每一次更新都會導致視圖重新結構化。 – MichaelD 2010-07-11 11:27:26