我正在测试索引视图的性能。以下是我使用的代码。 我正在使用AdventureWorks2012数据库。
- 创建测试表
SELECT *
INTO Person.Person_Test
FROM [Person].[Person]
go
SELECT *
INTO Person.PersonPhone_Test
FROM [Person].[PersonPhone]
go
SELECT *
INTO Person.BusinessEntityAddress_Test
FROM [Person].BusinessEntityAddress
go
SELECT *
INTO Person.Address_Test
FROM [Person].Address
go
SET STATISTICS IO ON
SET STATISTICS TIME ON
- 在表格上创建索引
CREATE CLUSTERED INDEX Person1 ON Person.Person_Test (BusinessEntityID);
CREATE CLUSTERED INDEX PersonPhone1 ON Person.PersonPhone_Test (BusinessEntityID);
CREATE CLUSTERED INDEX BusEntity1 ON Person.BusinessEntityAddress_Test (BusinessEntityID);
CREATE INDEX BusEntity2 ON Person.BusinessEntityAddress_Test (AddressId);
CREATE CLUSTERED INDEX AddressInd1 ON Person.Address_Test (AddressId);
- 根据四个表创建视图
CREATE VIEW My_View WITH SCHEMABINDING AS
SELECT P.BusinessEntityID,P.FirstName,P.LastName, PH.PhoneNumber,PH.PhoneNumberTypeID,BU.AddressID,AD.AddressLine1
FROM Person.Person_Test P
INNER JOIN Person.PersonPhone_Test PH
ON P.BusinessEntityID=PH.BusinessEntityID
INNER JOIN Person.BusinessEntityAddress_Test BU
ON P.BusinessEntityID=BU.BusinessEntityID
INNER JOIN Person.Address_Test AD
ON BU.AddressID=AD.AddressID
WHERE P.BusinessEntityID BETWEEN 50 AND 10000 AND AD.AddressID BETWEEN 100 AND 1000
GO
然后我测试没有索引的性能(Query1)
--Test regular view
SELECT BusinessEntityID,LastName,PhoneNumber,AddressID, AddressLine1
FROM My_View
WHERE BusinessEntityID between 50 and 200
我得到的信息是:
SQL Server parse and compile time:
CPU time = 0 ms, elapsed time = 8 ms.
SQL Server parse and compile time:
CPU time = 0 ms, elapsed time = 0 ms.
(91 row(s) affected)
Table 'Address_Test'. Scan count 91, logical reads 185, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'PersonPhone_Test'. Scan count 91, logical reads 184, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Person_Test'. Scan count 91, logical reads 286, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'BusinessEntityAddress_Test'. Scan count 1, logical reads 3, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 1 ms.
然后我在视图上添加索引
CREATE UNIQUE CLUSTERED INDEX idx_MyView ON My_View(BusinessEntityID);
go
但是,如果我重新运行上面的查询1,我收到相同的消息。 我还在这里附上执行计划。无论视图是索引还是未编入索引,执行计划都是相同的。
我错过了什么吗?为视图添加索引后为什么性能相同?
答案 0 :(得分:2)
视图条件比查询条件更具限制性。该视图的数据少于所需数据。
WHERE P.BusinessEntityID BETWEEN 50 AND 10000 AND AD.AddressID BETWEEN 100 AND 1000
VS
WHERE BusinessEntityID between 50 and 200
即使这是固定索引视图匹配非常脆弱并且可能失败。您可能需要使用NOEXPAND
强制它。
答案 1 :(得分:1)
感谢@mxix。 NOEXPAND给了我一个新消息。
SELECT BusinessEntityID,LastName,PhoneNumber,AddressID, AddressLine1
FROM My_View WITH (NOEXPAND)
WHERE BusinessEntityID between 50 and 200;
go
消息:
SQL Server parse and compile time:
CPU time = 0 ms, elapsed time = 0 ms.
SQL Server parse and compile time:
CPU time = 0 ms, elapsed time = 0 ms.
(91 row(s) affected)
Table 'My_View'. Scan count 1, logical reads 4, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 0 ms.
@FLICKER也是正确的,优化器非常聪明。
@usr指出了关键点。如果我使用
SELECT BusinessEntityID,LastName,PhoneNumber,AddressID, AddressLine1
FROM My_View
WHERE BusinessEntityID between 100 and 20000;
go
我不需要指定NOEXPAND。 SQL Server将自动在视图中使用索引。
SQL Server parse and compile time:
CPU time = 15 ms, elapsed time = 16 ms.
SQL Server parse and compile time:
CPU time = 0 ms, elapsed time = 0 ms.
(129 row(s) affected)
Table 'My_View'. Scan count 1, logical reads 5, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 0 ms.