小知识:迭代器

  在本篇文章,我将向大家介绍三个比较有趣的并且影响查询性能(内存、非阻塞vs.阻塞、动态游标)的迭代器。

内存:
   由于所有迭代器需要占用少量内存来存储状态信息等信息,因此执行查询前,我们并不能估算出所需内存的大小。当缓存执行计划时,可以缓存其分配的内存,以不再需要重新为其分配,从而加速该缓存计划的高效执行。
   但是,某些需要占用内存的迭代器可能需要额外的内存支持来执行,这些额外内存用于存储行数据。内存的大小通常由处理行的大小决定。为确保服务器运行不溢出内存,那些包含有占用内存的迭代器就可以顺利执行,由此我们可以估算出占用的内存量,从而在执行查询前为其保留内存授权。
   消耗内存的迭代器影响性能有以下几种方式:
   1) 消耗内存的迭代器查询可能需要一定的内存授权来执行,当服务器执行这样的查询时,若没有可用的内存,将会延迟执行而直接影响性能。
   2) 若存在过多争用少量内存资源的查询,则服务器可能面临并发性减少,这对于数据仓库来说并不会受影响,但对于OLTP应用则是不可接受的。
   3) 如果消耗内存的迭代器占用太多的少量内存,有可能执行时需要将数据写入(Spill)磁盘。Spilling可能会对查询造成一定的影响,同时系统性能也会由于额外的I/O负载增加而降低。此外,若迭代器写入过多的数据,有可能会溢出tempdb导致运行失败。

   消耗内存的迭代器主要有排序、哈希聚合、哈希联接。

   非阻塞与阻塞迭代器
   多数迭代器可以归纳为两类:
   1) 像在GetRows方法中同时使用输入行又产生输出行这样的迭代器,我们常把这类迭代器称为“非阻塞”。
   2) 在输出行前使用所有输入行(通常在Open方法)的迭代器,常称这类迭代器为“阻塞”或者说“停下来然后继续”。
 
   标量计算迭代器就是“非阻塞”迭代器的一个很好例子,而“排序”则是“阻塞”迭代器的一个例子。
   阻塞迭代器并不是总是消耗内存,例如上面提到的排序。像COUNT(*)、SUM(*)、MIN(*)、MAX(*)等等这类标量迭代器并不消耗内存但是使用的是阻塞,若不扫描完所有的数据并进行统计是不可能获得行数的。
   如果一个迭代器有两个子迭代器,该迭代器可能是阻塞也可能是非阻塞的。哈希联接就是这样一种迭代器。
   非阻塞迭代器常适用于OLTP查询的优化,尤其是对于TOP N查询或FAST N这样的查询更为适合。当使用EXISTS子查询也是利用“非阻塞”方式工作。
   提示:若一个查询需要输出有序,不妨创建索引来让优化器使用索引来快速输出期望的有序数据行,从而替代不必要的阻塞的排序操作,这种方法有助于提高查询的响应时间。
  


  

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/355374/viewspace-520653/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/355374/viewspace-520653/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值