首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 开源 FAQ 第二书店 博文视点 程序员
频道: 研发 数据库 中间件 信息化 视频 .NET Java 游戏 移动 服务: 人才 外包 培训
    图书品种:235680
       
热门搜索: ASP.NET Ajax Spring Hibernate Java

大结果集

Large Result Set

无论结果集是如何获得的,只要结果集“很大”,就符合我们下面要讨论的“大结果集”的情况。批处理环境下,产生大结果集是明智的。当需要返回大量记录时,只要查询条件的可选择性不高,那么即使结果集只占表中数据量的一小部分,也会引起DBMS引擎执行全表扫描;只有某些数据仓库例外,我们将在第10章中讨论之。

如果查询返回几万条记录,那么使用索引是没有意义的,无论索引用于产生最终结果,还是用于复杂查询的中间步骤。相比而言,借助哈希或合并连接进行全表扫描是合适的。当然,强力手段背后也必须有智慧:我们必须尽量扫描数据返回比例最高的表、索引,或者这两者的分区;扫描时的过滤条件必须是粗粒度的,从而返回的数据量比较大,使扫描更有价值;扫描显然违背了“尽快去除不必要数据”这一原则,但一旦扫描结束应立即重新贯彻该原则。

相反,采取扫描方式不合适的情况下,应尽量减少要访问数据的块数。为此,最常用的手段就是使用索引(而不是表),尽管所有索引的总数据量经常比表还大,但单个索引则远比表要小。如果索引包含了所有需要的信息,则扫描索引而不扫描表是相当合理的,可以利用诸如聚集索引等避免访问表的技术。

无论是要返回大量记录,还是要对大量记录进行检查,每条记录的处理都需小心。例如,一个性能不佳的用户自定义函数的调用,如果发生在“返回小结果集的 select 列表”中或在“可选择性很高的 where 子句”中,则影响不大;但返回大数据集的查询可能会调用这个函数几十万次,DBMS服务器就不堪重负了,这时必须优化代码。

还要重点关注子查询的使用。处理大量记录时,关联子查询(Correlated subquery)是性能杀手。当一个查询包含多个子查询时,必须让它们操作各不相同、自给自足的数据子集,以避免子查询相互依赖;到查询执行的最后阶段,多个子查询分别得到的不同数据集经过哈希连接或集合操作得到结果集。

查询执行的并行化(parallelism)也是个好主意,不过只应在“并发活动会话数(concurrently active sessions)”很少(典型情况为批处理操作)时才这么做。并行化是由 DBMS 实现的,如果有可能,DBMS把一个查询分割为多个并行运行的子任务,并由另一个专门的任务来协调。并发用户数很大时,并行化反而会影响处理能力。一般而言,并发用户数又多、要处理的信息量又大的情况下,最好做好战斗准备,因为这经常靠投入更多硬件来解决。

除了处理过程中由资源争用引起的等待之外,查询必须访问的数据量是影响“响应时间”的主要因素。但正如第4章讲过的,最终用户并不关心客观的数据量分析,他们只关心查询获得的数据。

查看所有评论(0)条】

最近评论



正在载入评论列表...
热点评论