根据我对查询如何编译、存储和检索查询计划的有限了解,我了解到多语句查询或存储过程将生成它的查询计划,该查询计划将存储在查询计划缓存中,供查询在未来的执行中使用。
我认为该计划是使用查询哈希从查询计划缓存中检索的,这意味着如果编辑和执行查询,则哈希会有所不同,并且会生成一个新计划,因为在查询计划缓存中找不到匹配的哈希。
我的问题是:如果用户执行的语句是多语句查询中的语句之一,它可以使用已经在缓存中的查询计划的相关部分进行多语句查询吗?我希望答案是否定的,因为散列值显然不匹配,但是在多语句查询中对每个语句进行散列是否更好,以便用户从查询中运行单个语句时可以使用它们?
我希望有一些我没有考虑到的并发症(我真正想知道的是这些)但似乎我们可以在许多查询计划中存储相同的“语句计划”,占用更多空间并占用更多空间CPU 和生成时间。
可能只是显示我的无知。
不是。SQL Server 中计划重用的基本单位是批处理。
为高水平计划重用而调整的系统会将公共代码(以合适的粒度)放置在 SQL Server 上的可重用对象(例如过程、函数、触发器)中。它还将显式参数化任何应用程序生成的或客户端代码。为了最大程度地重用计划,这些生成的批次应该仅在参数值上有所不同。
听起来您在问为什么SQL Server 被设计为在批处理级别而不是在语句级别进行缓存和重用。我怀疑除了最初的设计者之外还有谁能权威地回答这个问题。无论如何,在我看来,批处理是一种自然的粒度,因为它是相对独立的自然工作单元,代表了实现复杂性和计划重用概率之间的合理权衡。
有几件事使批处理不完全独立(例如跨存储过程边界创建和引用的本地临时表)。这些异常降低了正交性,并且多年来一直与意想不到的“设计”行为和错误相关联。