分类:
2008-04-24 10:44:07
当看到我们在本文前面使用的空间查询时,您会注意到,为了重叠测试,一个新的几何图形被构造成参数。现在,ST_LineString 构造函数是一个没有任何副作用的确定性的函数。DB2 优化器知道那些条件,它可以断定多次调用那个函数不会有害。取决于您的系统和查询,这可能是一个聪明的选择,但是也可能不是最佳的选择。例如,在使用 DPF 特性的分区环境中,在每个分区上构造 linestring,与在单独一个分区上构造几何图形,然后通过表队列将它分布到其他需要这个值的分区上相比,可能要好得多。在另一种场景中,为将进行空间重叠测试的每一行生成 linestring 又可能产生完全不同的结果。因此,可能有必要使用公共表表达式重新构造空间查询,以确保只调用一次构造函数。在清单 14 中,首先可以看到原有的查询,后面有一个重新构造的查询。这里执行的 SQL 脚本可以在 下载 一节中找到。这两个查询都表达了相同的语义,但是在我们的系统和数据库配置中,第二个查询运行起来要快 9%。
清单 14. 重构空间查询
$ db2batch -d testdb -f test_cte.sql -i complete -s on --------------------------------------------- Statement number: 1 SELECT id FROM roads2 WHERE db2gse.ST_Intersects(shape, db2gse.ST_LineString( 'linestring(10 50, 20 40)', 1003)) = 1 Prepare Time is: 0.000 seconds Execute Time is: 0.819 seconds Fetch Time is: 0.000 seconds Elapsed Time is: 0.819 seconds --------------------------------------------- Statement number: 2 WITH t(g) AS ( VALUES ( db2gse.ST_LineString('linestring(10 50, 20 40)', 1003) ) ) SELECT r.id FROM roads2 AS r, t WHERE db2gse.ST_Intersects(r.shape, t.g) = 1 Prepare Time is: 0.000 seconds Execute Time is: 0.744 seconds Fetch Time is: 0.000 seconds Elapsed Time is: 0.745 seconds --------------------------------------------- |
至此,我们讨论了很多提高空间操作性能的不同方面。现在我们将讨论最显著的一个方面,也就是对空间索引的使用。这里我们解释您应该做些什么,以便让 DB2 优化器选择使用一个空间索引。索引本身的调优在 下一节 中解释。
空间索引是建立在 DB2 可扩展索引框架(请参阅 参考资料 一节,找到关于 Index Extensions 的那篇文章)之上的一种扩展的索引。由于空间数据的多维特性,DB2 通常使用的 B* 树并不是很合适,因此 DB2 Spatial Extender 提供了专门的索引机制。DB2 索引扩展由三个部分组成:
DB2 Spatial Extender 已经定义了所有这些部分。除了真正创建一个空间索引外,您还必须熟悉最后一个部分。空间谓词是与比较两个几何图形的函数(即ST_Contains、ST_Within、ST_Intersects、ST_Crosses、ST_Overlaps、ST_Touches、ST_EnvIntersects、ST_MBRIntersects、ST_Equals 和ST_Distance)相关的谓词。其他任何空间函数都不能使用网格索引。而且,只有当上述函数中的一个函数出现在查询的 WHERE 子句中,并且该函数至少有一个参数标识出定义了网格索引的列的时候,才能使用空间网格索引。这听起来好像有一大堆的条件,但还是比较简单的:通过使用列可以找到索引,通过使用函数可以知道空间谓词。
此外,DB2 要求遵从基本的语法规则,以检测潜在的对空间谓词的使用。函数调用必须发生在针对值 1 进行的相等比较式的左边。一个例外是ST_Distance 函数,它必须出现在针对一个任意距离的小于比较式中。清单 15 给出了这两种正确的规范形式。
清单 15. 使用空间索引的语法规则
SELECT ... FROM |
图 3. 带有网格索引扫描的空间查询访问计划
前面我们解释过,DB2 优化器不完全知道空间网格索引的细节。而且,优化器很难判断那样的索引扫描的成本和选择性。DB2 开发小组目前选择的解决方案使用户可以提供对空间谓词选择性的估计。为此,可以在 WHERE 子句中将关键字SELECTIVITY 放在谓词的后面,后面带一个 0 到 1 之间的对选择性的估计值。这个值越低,优化器就越有可能选择扫描网格索引。清单 16 给出了一个查询例子,在这个查询中,向优化器提示空间谓词只有很少的符合条件的行。
清单 16. 为空间谓词指定选择性
SELECT ... FROM |