处理客户机的 SQL
SQL Server 还需要确定该命令是否是准备操作,这意味着该计划应该只编译但不执行。如果是准备操作,则 SQL Server 会给客户机返回一个句柄,供客户机在以后检索并执行该计划。如果不是一个准备操作,则 SQL Server 提取并执行该计划,就像最初从缓存中找到该计划一样。
准备/执行模型为缓存管理增加了复杂因素。预备给出了今后能够执行该计划的句柄。应用程序可以在几小时或几天之内保持该句柄是激活的,以定期执行计划。即使需要在缓存中为更多的活动计划或数据页面腾出空间,也不能使该句柄无效。SQL Server 实际所做的就是将计划放入缓存,此外还从预备操作中将 SQL 保存到更加紧凑的空间。如果空间紧张,则可按前述的方式释放计划所占用的空间,但仍有 SQL 的副本准备着。如果客户机要执行预备的 SQL,但在缓存中没有找到计划,则 SQL Server 能够检索到该文本并编译它,再将它放回缓存中。这样,缓存中的 16 千字节 (KB) 或更多的页面用来保存可重用的计划,而长期占用的空间或许是存储在其他处的 SQL 代码的 100 或 200 字节。
处理来自客户机的语句时的另一种情况是,查询是作为 SQL 语言事件出现的。除了一点以外,此流程并无太大的差异。在这种情况下,SQL Server 试图使用称为自动参数化的技术。SQL 文本与自动参数化模板相匹配。自动参数化是个棘手的问题,因此,过去一直能够利用共享的 SQL 的其他数据库管理产品, 一般并没有提供这一选项。随之而来的问题是,如果 SQL Server 自动地参数化每个查询,那么对于随后提交的某些特定值而言,这些查询中的某些(或绝大多数)将获得非常糟糕的计划。在程序员将参数标记放在代码之中的场合下,其假定是程序员知道所期望的值的范围,并愿意接受 SQL Server 提供的计划。但当程序员实际补充一个特定的值,并且 SQL Server 决定将该值当做一个可变的参数来对待时,所产生的任何适合于某个值的计划可能不适合于后续的值。利用存储过程,通过在过程中放入 WITH RECOMPILE 选项,程序员可以强制产生新的计划。利用自动参数化,程序员无法指出必须为每一个新值开发新的计划。