Microsoft SQL Server 查询处理器的内部机制与结…
2008-02-23 05:36:23来源:互联网 阅读 ()
另一个问题随之而来。一旦您开始允许查询使用大量内存,就必须确定如何把内存分配给可能需要内存的很多查询。 SQL Server 按照以下方法解决这个问题。当查询计划优化之后,优化器要确定有关给该查询使用的内存的两部分信息。第一,该查询有效执行所需要的最小内存,该参数与查询计划一起存放。优化器还要确定该查询可以获益的最大的内存量。例如,如果要排序的整个表只有 100MB,分配 2GB 内存就没什么帮助了。您需要的只是 100MB,这个最大有用内存参数随查询计划一起存放。
当 SQL Server 开始执行计划时,该计划被传递给一个所谓内存授权调度程序的例程中。这个授权调度程序要完成几项有趣的工作。首先,如果授权调度程序要处理的查询在计划中没有排序或杂凑操作,则 SQL Server 知道该查询不会需要很多内存。在这种情况下,不需要内存授权调度程序进行判断。该计划会立即执行,因此典型的事务处理请求会完全旁路这种判断机制。内存授权调度程序还设有多个队列处理不同容量的请求。内存调度程序优先处理较小的请求。例如,如果有一个查询要求“提取前 10 个”,并且只需要对 20 行排序,则虽然需要经过内存授权调度程序,但是要释放该查询并且很快调度。服务器需要并行或并发执行许多这种查询。
如果有很大的查询,您希望一次只运行几个查询,让它们占有所需的更多内存。SQL Server 确定一个由 4 X(系统中的 CPU 个数)得到的数。如果可能,SQL Server 会同时运行那个数量的查询,为它们分配高效运行所需要的最小内存。如果还剩有内存,则一部分查询会允许占用最大高效内存。SQL Server 试图既为查询分配尽可能多的内存,又让尽可能多的查询同时运行在系统中。
能够使用最大高效内存对某些操作很重要,例如夜间运行的批处理过程。您可能会生成很大的报表,或重新建立索引。这些查询可能使用大量内存,这种机制可以动态调整对内存的需求。因此,如果如果在队列中等待处理的查询不多,则内存授权调度程序会经常分配给查询最大需要的内存。如果白天的机器负载很重,则就不能同时运行太多的查询。这些查询会得到有效运行所需最小的内存,让内存为更多的查询共享。
一旦调度程序说现在可以为请求分配内存,则计划即被“打开”,开始实际运行。计划会一直运行直到完成。如果查询使用了默认结果集模型,则计划会一直运行到检索到所有结果为止,然后把结果返回给客户机。如果使用的是游标模型,则处理过程略有不同。每个客户机请求只提取一块数据,并不是所有数据。当每个结果块返回给客户机之后,SQL Server 必须等待客户机的下一个请求。在等待时,整个计划就会睡眠。这意味着要释放一些锁,要释放一些资源,并保留一些断点信息。这些断点信息使得 SQL Server 能够返回到睡眠之前的状态,使得执行可以继续。
过程缓存
我们在前面已经多次提到 SQL Server 的过程缓存。需要注意的是,SQL Server 7.0 的过程缓存与以前的版本有很大不同。在早期的版本中,有两个有效配置值用于控制过程缓存的容量:一个是定义 SQL Server 总可用内存的固定容量,另一个是供存储查询计划使用的内存百分比(扣除满足固定需要的内存)。在老版本中,特定 SQL 语句从不存入缓存,只有存储过程计划才存入其中。在 SQL Server 7.0 中,内存的总容量是动态的,用于查询计划的空间也是经常变化的。
在处理查询时,SQL Server 7.0 首先会问的是:这个查询既是特定的又是易于编译的吗?如果是,SQL Server 就根本不会将其写入缓存中。将来重新编译这些计划比把复杂的计划或数据页推出内存更合算。如果查询不是特定的或不易于编译,则 SQL Server 会从缓存区中分配一些缓存内存存储该计划,因为该缓存区是 SQL Server 7.0 用来满足 99% 内存需求的唯一来源。在少数特殊情况下,SQL Server 会直接从操作系统中分配大块内存,但是这种情况极为罕见。SQL Server 的管理是集中式的。
写入缓存的除计划外,还有反映通过编译该查询实际创建该计划的成本的成本因子。如果这是一个特定计划,则 SQL Server 将它的成本设置为 0,表示可以立即将它撤出过程缓存。对于特定 SQL,虽然有可能被重复使用,但可能性很小,如果系统内存紧张,总是愿意首先撤出特定语句的计划。这样,特定查询的计划是最适合清出缓存的对象。如果查询不是特定的,则 SQL Server 会把该成本设置为实际编译查询的成本。这些成本是以磁盘 I/O 为单位的。如果从磁盘中读出一个数据页,则有一个 I/O 成本。在编译计划时,信息从磁盘中读出,包括统计数据和查询本身的文本。SQL 要进行附加的处理,而且这处理工作被正常化为 I/O 成本。现在,建立过程的成本可用执行 I/O 的成本表示。该成本非常恰当反映了,与打算用磁盘缓存的数据量相比,管理实际打算分配给存储过程和任何种类查询计划的缓存量的能力。该成本被计算出来之后,该计划就会被写入缓存。
图 8 显示计算计划成本并将其写入缓存的流程。
图 8. 将计划写入缓存
如果另一个查询可以重新使用该计划,则 SQL Server 要再次判定计划的类型。如果是一个特定计划,SQL Server 会把成本加 1。这样,如果特定计划确实要被重新使用,则它会在缓存中稍作停留,停留时间越长,成本就增加越多。如果该计划经常被重新使用,则成本会一次增加一个单位地不断增长,直到增长到其实际编译成本。该成本和设置的成本一样高。不过该计划经常被重复使用;如果同一用户或其他用户不断重新提交完全一样的 SQL 文本,该计划就会留在缓存中。
如果查询不是特定的,也就是说是一个存储过程、带参数的查询或自动参数化的查询,则每次该计划被重新使用时,成本都会设置回原来的值。只要计划被重新使用,就会留在缓存中。即使有一段时间没有被使用,取决于最初的编译代价的高低,计划停留在缓存中的时间也有长短。
图 9 显示从缓存中检索计划并调整成本的流程。
图 9. 从缓存中检索计划
迟缓写入器(Lazywriter) 是使计划过时的机制,负责在必要的时候从缓存中删除计划。迟缓写入器实际上是存储引擎的一部分,但是因为迟缓写入器对于查询处理机制是如此重要,我们还是在这里进行讨论。迟缓写入器管理查询计划内存使用的机制与管理页面的机制一样,因为 SQL Server 7.0 计划存储在普通缓冲存储器中。迟缓写入器要检查系统中所有的缓冲器标题。如果系统的内存不紧张,检查的次数就很少;如果开始紧张,则迟缓写入器就会经常运行。当迟缓写入器运行时,它要检查缓冲区标题,并检查缓存区中该页面的当前成本。如果成本为 0,则意味着自从上次迟缓写入器检查以来,该页面没有被使用过,于是迟缓写入器就会释放该页面,以便为系统增加可用内存,用于页面 I/O 或其他计划。此外,如果该缓冲区包含过程计划,则迟缓写入器会调用 SQL 管理器,以完成一些清理工作。最后,该缓冲区会被放到可用内存表中供重新使用。
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- Microsoft SQL Server 查询处理器的内部机制与结构(1) 2008-02-23
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash
