Question

In SQL Server, stored procedures execution plans are cached but view execution plan are never cached. Is that true? If yes, why does SQL Server not cache view execution plans?

If a optimizer is taking a long time to create execution plan, is it helpful to wrap the query in a view?

Was it helpful?

Solution

There is no such thing as an execution plan for a view (at best, a parse tree is cached). View is always optimized as a part of the outer query (somewhat simplified, the text of the view is merged with text of the outer query and then optimized).

Will an execution plan of a query using a view be cached or not depends on the very same factors as with any other query.

OTHER TIPS

Here are some of my findings

Test Table

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

View on that table

CREATE VIEW vw_Test_View
AS
SELECT ID, SUM(Value) AS Total 
FROM Test_Table
GROUP BY ID
GO

Clear_Chached Plans

-- Clear chache for any chached plans 
-- (Warning do not execute this on Production server)

DBCC FREEPROCCACHE;
GO

Calling View

-- 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                                                                                                                                                                                             ║
╚═══════════╩═══════════════╩═════════╩════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝

Conclusion

As you can see the execution plan for our SELECT * FROM View was compiled once and reused on second execution of the same query.

It is a view, Plan was chached and it was reused on subsequent execution. Hope this explanation helps . Thank you.

A view is never executed. When it is used as part of a query it is inlined into the query plan as if you had text-pasted its definition. The query optimizer knows nothing about views (except for indexed views).

After inlining of the view definition all the usual caching rules apply. In other words the query is normally cached.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top