神秘的 DB2 排序
2009-11-16 00:00:00 来源:WEB开发网对于示例中的 SQL,DB2 依次评估每个索引。我们来看看 DB2 可以考虑采用的众多访问路径中的四种:
如果使用第一个索引,DB2 可以匹配 lastname、以传统方式使用此索引并按照索引次序获取表行。在读取表行时,对每一行应用 workdept 上的谓词。对于符合条件的每一行,DB2 获取 lastname、workdept 和 jobcode 。不需要执行排序。但是,如果表不是按照 lastname 次序排列的,读取会是随机和同步的。
如果使用第一个索引,DB2 可以匹配 lastname 并以另一种非传统的列表预抓取方式使用此索引。 DB2 读取索引并找出 lastname 大于或等于主机变量的所有索引指针 (RID) 。然后,DB2 按照 RID 次序对这些 RID 排序(也就是按照表页面次序和 ID 映射项次序)。获得有序的 RID 列表之后,DB2 可以使用此列表连续获取表页面 / 行,异步地把页面预抓取到缓冲区池中。通过使用有序的 RID 列表,DB2 找到预抓取的页面上的每个表行,应用 workdept 上的谓词,如果表行满足 lastname 谓词和 jobcode 谓词,就获取选择的三列。因为其中的 RID 排序会打乱索引次序,所以需要执行数据排序以满足 ORDER BY lastname 子句的要求。
如果使用第二个索引,DB2 可以匹配两列(workdept 和 lastname)。由于与两列进行匹配,DB2 读取的表行更少(只包括同时满足两个谓词的表行)。对于读取的每个表行,DB2 获取 workdept、lastname 和 jobcode 。需要按照 lastname 次序对符合条件的行排序。
如果使用第三个索引,DB2 不能匹配任何谓词,但是可以通过检查 lastname 和 workdept 对索引数据应用谓词。对于每个符合条件的索引行,DB2 可以从索引本身获取所选的三列,因此避免读取表。另外,因为此索引的第一列是 lastname,数据会按照 lastname 次序返回。不需要排序。
这个神秘现象的本质
如果有 ORDER BY 子句,DB2 会尝试避免排序(并不保证一定避免排序,但是它会考虑这一因素)。上面的访问路径 1 和 4 使 DB2 能够在不执行排序的情况下以所需的次序获得符合条件的行。
如果删除 ORDER BY 子句,DB2 就不会尝试避免排序。其他因素就变得更重要了,比如避免同步读取。访问路径 2 和 3(但不包括最后的数据排序)就变得更有吸引力了。
通过考虑访问路径 1 和 2,就可以理解添加 ORDER BY 子句为什么可能消除排序,而删除 ORDER BY 可能会导致排序。如果添加 ORDER BY 子句,DB2 可能倾向于选择访问路径 1,不执行排序;如果删除 ORDER BY,DB2 可能选用不执行最后数据排序的访问路径 2 。但是,访问路径 2 包含另一个排序,即 RID 排序。因此,删除 ORDER BY 子句实际上可能在访问路径中引入排序。
尽管在访问路径 1 和 2 中 DB2 选择的索引是相同的,但是 ORDER BY 子句导致 DB2 以传统方式使用索引,从而避免排序。删除 ORDER BY 子句导致 DB2 以列表预抓取方式使用索引,这种方式在获取表页面之前执行一次 RID 排序。
解释了最后一个神秘现象
现在,我们已经解释了 DB2 中的另一个神秘现象。
- ››db2 对float类型取char后显示科学计数法
- ››DB2中出现SQL1032N错误现象时的解决办法
- ››DB2 锁升级示例
- ››db2诊断系列之---定位锁等待问题
- ››db2 命令选项解释
- ››DB2 最佳实践: 使用 DB2 pureXML 管理 XML 数据的...
- ››DB2 9.5 SQL Procedure Developer 认证考试 735 准...
- ››DB2 9.5 SQL Procedure Developer 认证考试 735 准...
- ››DB2 9.5 SQL Procedure Developer 认证考试 735 准...
- ››DB2 基础: 表空间和缓冲池
- ››DB2 XML 编程,第 1 部分: 理解 XML 数据模型
- ››DB2 pureScale 实战
更多精彩
赞助商链接