在SQL Server中,缓存存储过程执行计划,但从不缓存视图执行计划。真的吗?如果是,为什么SQL Server不缓存视图执行计划?
如果优化器花费很长时间来创建执行计划,将查询包装在视图中会有帮助吗?
答案 0 :(得分:8)
没有视图的执行计划(最好是缓存一个解析树)。视图始终作为外部查询的一部分进行优化(稍微简化,视图文本与外部查询的文本合并,然后进行优化)。
使用视图的查询的执行计划是否会被缓存取决于与任何其他查询完全相同的因素。
答案 1 :(得分:6)
以下是我的一些发现
测试表
CREATE TABLE Test_Table (ID INT , Value INT)
GO
INSERT INTO Test_Table
VALUES
(1, 100),
(2, 100),(2, 100),
(3, 100),(3, 100),(3, 100)
GO
在该表格上查看
CREATE VIEW vw_Test_View
AS
SELECT ID, SUM(Value) AS Total
FROM Test_Table
GROUP BY ID
GO
Clear_Chached计划
-- Clear chache for any chached plans
-- (Warning do not execute this on Production server)
DBCC FREEPROCCACHE;
GO
致电观看
-- Execute the same select from view twice
SELECT * FROM dbo.vw_Test_View
GO
SELECT * FROM dbo.vw_Test_View
GO
Chached Plans Inspection
-- Inspect Chached execution plans
SELECT UseCounts, Cacheobjtype, Objtype, [TEXT]
FROM sys.dm_exec_cached_plans
CROSS APPLY sys.dm_exec_sql_text(plan_handle)
WHERE [TEXT] LIKE '%vw_Test%'
GO
╔═══════════╦═══════════════╦═════════╦════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╗
║ UseCounts ║ Cacheobjtype ║ Objtype ║ TEXT ║
╠═══════════╬═══════════════╬═════════╬════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╣
║ 1 ║ Compiled Plan ║ Adhoc ║ SELECT UseCounts, Cacheobjtype, Objtype, TEXT, query_plan FROM sys.dm_exec_cached_plans CROSS APPLY sys.dm_exec_sql_text(plan_handle) CROSS APPLY sys.dm_exec_query_plan(plan_handle) WHERE [TEXT] LIKE '%vw_Test%' ║
║ 2 ║ Compiled Plan ║ Adhoc ║ SELECT * FROM dbo.vw_Test_View ║
╚═══════════╩═══════════════╩═════════╩════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝
<强>结论强>
正如您所看到的,SELECT * FROM View
的执行计划已编译一次,并在第二次执行同一查询时重复使用。
这是一个观点,计划被追逐,并在随后的执行中重复使用。希望这个解释有所帮助谢谢。
答案 2 :(得分:3)
永远不会执行视图。当它用作查询的一部分时,它将内联到查询计划中,就像您已对其定义进行了文本粘贴一样。查询优化器对视图一无所知(索引视图除外)。
在内联视图定义之后,所有常用的缓存规则都适用。换句话说,查询通常是缓存的。