【问题标题】:Does SQL Server cache execution plan of a view?SQL Server 是否缓存视图的执行计划?
【发布时间】:2014-06-20 04:43:26
【问题描述】:

在 SQL Server 中,存储过程执行计划被缓存,但视图执行计划从不被缓存。真的吗?如果是,为什么 SQL Server 不缓存视图执行计划?

如果优化器需要很长时间来创建执行计划,将查询包装在视图中是否有帮助?

【问题讨论】:

  • 可能是存储视图的平面图不是很有用,因为在实践中总是需要对视图进行操作。该操作的计划被缓存。这涉及视图查询的可能转换。
  • 您从哪里得到这些错误信息?视图上的SELECT 最终实际上是一个选择查询,并且与任何其他查询一样,它的执行计划将被缓存 - 它与临时查询或内部查询没有什么不同一个存储过程......一个查询是一个查询是SQL Server中的一个查询,所有的执行计划都被缓存(直到从缓存中驱逐)
  • @marc_s:我认为问题在于视图DDL SQL是否被缓存。

标签: sql-server view database-performance


【解决方案1】:

没有视图执行计划之类的东西(充其量是缓存解析树)。视图始终作为外部查询的一部分进行优化(稍微简化,视图的文本与外部查询的文本合并,然后进行优化)。

是否会缓存使用视图的查询的执行计划取决于与任何其他查询完全相同的因素。

【讨论】:

    【解决方案2】:

    这是我的一些发现

    测试表

    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 计划检查

    -- 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 的执行计划被编译一次,并在第二次执行相同查询时重复使用。

    这是一个视图,计划已被查明,并在后续执行中被重用。希望这个解释有帮助。谢谢你。

    【讨论】:

    • 这似乎具有误导性。执行播放是“从视图中选择内容”并且 that 被缓存。但是视图本身的执行计划(这是一个不同的“从表中选择内容”)呢?
    • @M.Ali 你错了。正如 jcollum 所说,视图本身的执行计划没有被缓存。
    【解决方案3】:

    视图永远不会被执行。当它用作查询的一部分时,它被内联到查询计划中,就好像您已将其定义粘贴到文本中一样。查询优化器对视图一无所知(索引视图除外)。

    内联视图定义后,所有常用的缓存规则都适用。换句话说,查询通常会被缓存。

    【讨论】:

    • 如果我们执行SELECT * FROM dbo.VeiwName,这将为该查询创建一个计划,如果我们再次执行相同的查询,它不会重用为第一次执行创建的执行计划吗?
    • 视图本身没有被执行——是的——但是视图上的任何SELECT最终都会导致对基础表的常规SELECT查询,并且SELECT查询将有一个执行计划,并且该计划将被缓存,就像任何其他执行计划一样.....
    • @M.Ali 当然会被缓存。使用视图不会以任何方式使查询变得特别。通常的缓存规则适用。
    • @usr 如果视图在使用时被内联到查询中,索引视图有什么用?
    • @RandomUser 这是一个非常聪明的问题。优化器稍后将部分查询匹配到索引视图。无论您是引用了视图还是复制粘贴了视图文本,它都会执行此操作。它无法区分。匹配引擎适用于内联查询。是的,这意味着有时SELECT * FROM MyView 确实 使用索引!匹配引擎不是那么好,唉。它开始因许多连接或其他复杂的东西而失败。有NOEXPAND (这是一个自己动手的解决方案)。
    猜你喜欢
    • 1970-01-01
    • 2011-03-06
    • 2012-02-18
    • 1970-01-01
    • 2019-04-13
    • 2011-06-13
    • 2020-10-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多