当前位置: 代码迷 >> Sql Server >> 直接查询一个索引视图,但是执行计划显示并没有查询索引视图,查询的还是基础表?该怎么处理
  详细解决方案

直接查询一个索引视图,但是执行计划显示并没有查询索引视图,查询的还是基础表?该怎么处理

热度:164   发布时间:2016-04-27 14:08:21.0
直接查询一个索引视图,但是执行计划显示并没有查询索引视图,查询的还是基础表?
USE AdventureWorks
GO

-- 建立索引视图时, 必须满足的选项设置
SET QUOTED_IDENTIFIER, ANSI_NULLS ON
GO

-- 建立视图
CREATE VIEW Sales.v_SaleOrders
WITH SCHEMABINDING -- 索引视图要求必须具有此项
AS
SELECT 
O.OrderDate, OD.ProductID,
Revenue = SUM(OD.UnitPrice * OD.OrderQty * (1 - OD.OrderQty)),
ItemCount = COUNT_BIG(*) -- 索引视图中必须用COUNT_BIG
FROM Sales.SalesOrderHeader O
INNER JOIN Sales.SalesOrderDetail OD
ON O.SalesOrderID = OD.SalesOrderID
GROUP BY O.OrderDate, OD.ProductID
GO
-- 在视图上建立索引
CREATE UNIQUE CLUSTERED INDEX IXUC_ProductID_OrderDate
ON Sales.v_SaleOrders(
ProductID, OrderDate)
GO

-- 执行与视图相关的查询
SET SHOWPLAN_TEXT ON
GO 
SELECT * FROM Sales.v_SaleOrders --WITH(INDEX = IXUC_ProductID_OrderDate)
GO
SET SHOWPLAN_TEXT OFF
GO

-- 删除演示环境
DROP VIEW Sales.v_SaleOrders


/*

StmtText
----------------------------------------
SELECT * FROM Sales.v_SaleOrders --WITH(INDEX = IXUC_ProductID_OrderDate)

(1 row(s) affected)

StmtText
---------------------------------------------------------------------------------------------------------------------------------------------------------------------
  |--Parallelism(Gather Streams)
  |--Hash Match(Aggregate, HASH:([O].[OrderDate], [OD].[ProductID]), RESIDUAL:([AdventureWorks].[Sales].[SalesOrderHeader].[OrderDate] as [O].[OrderDate] = [AdventureWorks].[Sales].[SalesOrderHeader].[OrderDate] as [O].[OrderDate] AND [AdventureWorks].[Sales].[SalesOrderDetail].[ProductID] as [OD].[ProductID] = [AdventureWorks].[Sales].[SalesOrderDetail].[ProductID] as [OD].[ProductID]) DEFINE:([Expr1004]=SUM([Expr1006]), [Expr1005]=COUNT(*)))
  |--Parallelism(Repartition Streams, Hash Partitioning, PARTITION COLUMNS:([O].[OrderDate], [OD].[ProductID]))
  |--Hash Match(Inner Join, HASH:([O].[SalesOrderID])=([OD].[SalesOrderID]))
  |--Parallelism(Repartition Streams, Hash Partitioning, PARTITION COLUMNS:([O].[SalesOrderID]))
  | |--Clustered Index Scan(OBJECT:([AdventureWorks].[Sales].[SalesOrderHeader].[PK_SalesOrderHeader_SalesOrderID] AS [O]))
  |--Compute Scalar(DEFINE:([Expr1006]=([AdventureWorks].[Sales].[SalesOrderDetail].[UnitPrice] as [OD].[UnitPrice]*CONVERT_IMPLICIT(money,[AdventureWorks].[Sales].[SalesOrderDetail].[OrderQty] as [OD].[OrderQty],0))*CONVERT_IMPLICIT(money,(1)-CONVERT_IMPLICIT(int,[AdventureWorks].[Sales].[SalesOrderDetail].[OrderQty] as [OD].[OrderQty],0),0)))
  |--Parallelism(Repartition Streams, Hash Partitioning, PARTITION COLUMNS:([OD].[SalesOrderID]))
  |--Clustered Index Scan(OBJECT:([AdventureWorks].[Sales].[SalesOrderDetail].[PK_SalesOrderDetail_SalesOrderID_SalesOrderDetailID] AS [OD]))

(9 row(s) affected)
*/

------解决方案--------------------
没看到他
------解决方案--------------------
搬个板凳看.

------解决方案--------------------
楼主,你的代码在我这里执行出来的结果是不一样的,我的是:
|--Clustered Index Scan(OBJECT:([AdventureWorks].[Sales].[v_SaleOrders].[IXUC_ProductID_OrderDate]))
------解决方案--------------------
SQL code
当满足下列条件时,SQL Server 查询优化器使用索引视图: 下列会话选项均设置为 ON: ANSI_NULLSANSI_PADDINGANSI_WARNINGSARITHABORTCONCAT_NULL_YIELDS_NULLQUOTED_IDENTIFIER NUMERIC_ROUNDABORT 会话选项设置为 OFF。查询优化器查找视图索引列与查询中的元素之间的匹配,例如: WHERE 子句中的搜索条件谓词联接操作聚合函数GROUP BY 子句表引用估计的索引使用成本是查询优化器考虑使用的所有访问机制中的最低成本。 查询中引用(直接或通过展开视图访问其基础表)的且与索引视图中的表引用相对应的每个表在该查询中都必须具有应用于表的相同提示集。 注意:在此上下文中,不管当前的事务隔离级别是什么,READCOMMITTED 和 READCOMMITTEDLOCK 提示始终被认为是不同的提示。 ANSI_NULLSANSI_PADDINGANSI_WARNINGSARITHABORTCONCAT_NULL_YIELDS_NULLQUOTED_IDENTIFIER NUMERIC_ROUNDABORT 会话选项设置为 OFF。除 SET 选项和表提示的要求外,查询优化器也使用上述规则确定表索引是否包含查询。不必在查询中指定其他内容即可使用索引视图。查询不必在 FROM 子句中显式引用索引视图,查询优化器即可使用该索引视图。如果查询所引用的基表中的列也同时存在于索引视图中,并且,查询优化器估计使用索引视图将提供最低成本的访问机制,则查询优化器会选择索引视图,其方式类似于当查询中不直接引用基表索引时选择基表索引。当视图中包含非查询所引用的列时,只要视图提供包含一个或多个查询中所指定列的最低成本选项,查询优化器即可能选择该视图。查询优化器将 FROM 子句中引用的索引视图视为标准视图。查询优化器在优化进程开始时将视图的定义展开至查询中。然后,执行索引视图匹配。可以将索引视图用于优化器选择的最终执行计划中,或该计划可以通过访问视图引用的基表来具体化由视图得到的必要数据。优化器会选择成本最低的方式。