Sql server 索引不会影响索引视图中的查询性能
我想检查索引视图上的查询性能 我基于Sql server 索引不会影响索引视图中的查询性能,sql-server,performance,sql-server-2008,view,indexing,Sql Server,Performance,Sql Server 2008,View,Indexing,我想检查索引视图上的查询性能 我基于Northwind数据库中的Product表创建了一个包含所有列的视图。创建视图后,我在视图上添加了聚集索引(因为我无法创建没有int的非聚集索引) 现在,在添加非聚集索引之前,请检查以下查询执行计划和统计信息: SELECT [ProductName] ,[QuantityPerUnit] ,[UnitPrice] ,[UnitsInStock] ,[UnitsOnOrder] ,[ReorderLevel] ,[Discontinu
Northwind
数据库中的Product
表创建了一个包含所有列的视图。创建视图后,我在视图上添加了聚集索引(因为我无法创建没有int的非聚集索引)
现在,在添加非聚集索引之前,请检查以下查询执行计划和统计信息:
SELECT [ProductName]
,[QuantityPerUnit]
,[UnitPrice]
,[UnitsInStock]
,[UnitsOnOrder]
,[ReorderLevel]
,[Discontinued]
FROM [Northwind].[dbo].[test_IndexedView]
WHERE UnitPrice = 21.35
然后我创建了一个索引:
CREATE NONCLUSTERED INDEX [idx_Unitp] ON [dbo].[test_IndexedView]
(
[UnitPrice] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
我再次执行这个查询,但没有任何变化。不在执行计划中,也不在统计中
问题在哪里?如何使用索引视图提高性能
编辑1) 我创建一个视图:
CREATE VIEW [dbo].[indexView]
WITH SCHEMABINDING
AS
SELECT ProductName, SupplierID, CategoryID, QuantityPerUnit, UnitPrice, UnitsInStock, UnitsOnOrder, Discontinued, ReorderLevel
FROM dbo.Products
GO
然后,当我想在上面创建一个“非聚集索引”时,如下所示:
CREATE NONCLUSTERED INDEX [idx_Unitp] ON [dbo].[IndexView]
(
[UnitPrice] ASC
)
我得到这个错误:
味精1940,第16级,状态1,第1行无法在视图“dbo.IndexView”上创建索引。它没有唯一的聚集索引 所以我不得不创建一个聚集索引 索引前后的执行计划都是
索引扫描
SELECT@@VERSION
的结果是:
Microsoft SQL Server 2008(SP2)-10.0.4000.0(英特尔X86)2010年9月16日20:09:22版权所有(c)1988-2008微软公司
Windows NT 6.1上的企业版(版本7600:)
由于您要从表中选择7列,并且索引本身只包含
UnitPrice
,因此SQL Server查询优化器仍然认为扫描比使用索引查找价格,然后对找到的每一行执行键查找以获取其他列更有效
我敢打赌,如果你像这样在索引中包含其他列
CREATE NONCLUSTERED INDEX [idx_Unitp]
ON [dbo].[test_IndexedView] ([UnitPrice] ASC)
INCLUDE(ProductName, QuantityPerUnit, UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued)
然后将使用该索引——几乎可以肯定
实际使用非聚集索引的要求相当严格——比大多数人一开始相信的要严格得多。选择性必须非常非常高——有时小于1%——才能考虑指数。此外,返回的行总数(以及获取其余数据所需的键查找总数)也需要很小
你最好的选择总是有一个覆盖索引,一个包含满足查询所需的所有信息(所有列)的索引,在这种情况下,使用NC索引的可能性会显著增加。你说“我被迫创建聚集索引”。但不要给出定义。由于视图上的聚集索引需要是唯一的,我在视图定义中添加了ProductID
,并假定
CREATE UNIQUE CLUSTERED INDEX [idx_Unitp] ON [dbo].[IndexView]
(
[UnitPrice] ASC, ProductID ASC
)
然后,我看到了与您相同的基本表上的扫描
除非当平面图在视图上显示seek时,我将查询更改为使用[Northwind].[dbo].[IndexView]中的和(NOEXPAND)
原因是。初始查询得到一个简单的计划,成本仅为0.0033667
。优化者在获得索引视图匹配之前选择此计划
无论如何,这并不是索引视图的好用法。直接在基表上创建索引会更好
CREATE NONCLUSTERED INDEX ixNoView
ON dbo.Products (UnitPrice)
INCLUDE ( ProductName,
QuantityPerUnit,
UnitsInStock,
UnitsOnOrder,
Discontinued,
ReorderLevel)
这比视图上的聚集索引窄,因为它只有7列而不是10列,并且避免了索引视图匹配的问题,并且对于其他开发人员来说更容易发现
现在使用非索引视图
CREATE VIEW [dbo].[nonIndexedView]
AS
SELECT ProductName,
SupplierID,
CategoryID,
QuantityPerUnit,
UnitPrice,
UnitsInStock,
UnitsOnOrder,
Discontinued,
ReorderLevel,
ProductID
FROM dbo.Products
询问
SELECT [ProductName]
,[QuantityPerUnit]
,[UnitPrice]
,[UnitsInStock]
,[UnitsOnOrder]
,[ReorderLevel]
,[Discontinued]
FROM dbo.nonIndexedView
WHERE UnitPrice = 21.35
显示索引搜索
我添加了
中的列包括
部分,但不随索引或不随索引变化it@Kerezo:好的,您使用的是哪个版本的SQL Server??您还没有告诉我们在索引视图中聚集索引是由什么组成的。。。。请同时发布执行计划,以便我们了解happens@Kerezo:无法复制此内容;一旦我用覆盖列创建了非聚集索引,在我的例子中,执行计划将从聚集索引扫描切换到新创建的非聚集索引上的索引搜索……亲爱的@marc_s我执行了您的脚本,但我不知道您是否相信我,但有一个奇怪的问题。我的查询执行计划在创建索引后没有更改:(.我不知道问题出在哪里:(@Kerezo:你能检查一下你的Northwind
数据库的兼容性级别吗?从sys.databases where name='Northwind'