简体   繁体   English

为什么索引视图不会改善性能?

[英]Why indexed view doesn't improve the performance?

I am testing the performance of an indexed view. 我正在测试索引视图的性能。 Below are the codes that I used. 以下是我使用的代码。 I am using AdventureWorks2012 Database. 我正在使用AdventureWorks2012数据库。

--Create test tables - 创建测试表

 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 indexes on tables - 在表上创建索引

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 a view based on the four tables - 根据四个表创建视图

 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

Then I test the performance without index (Query1) 然后我测试没有索引的性能(Query1)

--Test regular view 
SELECT BusinessEntityID,LastName,PhoneNumber,AddressID, AddressLine1
FROM My_View
WHERE BusinessEntityID between 50 and 200

The message I got is : 我得到的信息是:

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.

Then I add index on the view 然后我在视图上添加索引

CREATE UNIQUE CLUSTERED INDEX idx_MyView ON My_View(BusinessEntityID);
go

However, I got the same message if I rerun the above Query 1. I also attach the Execution plan here. 但是,如果我重新运行上面的查询1,我会收到相同的消息。我还在此附上执行计划。 Both the Execution plans are the same, no matter the view is indexed or not indexed. 无论视图是索引还是未编入索引,执行计划都是相同的。 在此输入图像描述 在此输入图像描述

Is there something that I missed? 有什么我错过了吗? Why the performance is the same after I add index to the view? 为视图添加索引后,为什么性能相同?

The view condition is more restrictive than the query condition. 视图条件比查询条件更具限制性。 The view has less data than required. 视图的数据少于所需数据。

WHERE P.BusinessEntityID BETWEEN 50 AND 10000 AND AD.AddressID BETWEEN 100 AND 1000

vs.

WHERE BusinessEntityID between 50 and 200

Even when that is fixed indexed view matching is very fragile and can fail. 即使这是固定索引视图匹配非常脆弱并且可能失败。 You might need to force it using NOEXPAND . 您可能需要使用NOEXPAND强制它。

Thanks to @mxix . 感谢@mxix NOEXPAND gives me a new message. NOEXPAND给了我一个新消息。

SELECT BusinessEntityID,LastName,PhoneNumber,AddressID, AddressLine1
FROM My_View WITH (NOEXPAND)
WHERE BusinessEntityID between 50 and 200;
go

The message: 消息:

 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 is also right that optimizer is very smart. @FLICKER也是对的,优化器非常聪明。


@usr points out the key point. @usr指出了关键点。 If I use 如果我使用

SELECT BusinessEntityID,LastName,PhoneNumber,AddressID, AddressLine1
FROM My_View 
WHERE BusinessEntityID between 100 and 20000;
go

I don't need to specify NOEXPAND. 我不需要指定NOEXPAND。 SQL Server will use the index in view automatically. 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.

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM