12. 尽量将区间谓词重写为Between谓词

假设一个查询性能不佳,它的主要筛选谓词之一是一个区间谓词,如下所示:

 

  1. WHERE HIREDATE  > :HV-DATE 

如果数据库管理器没有使用HIREDATE列上的索引,你可能希望尽量让它使用这个索引,那么可以如下编写代码:

 

  1. WHERE HIREDATE  BETWEEN  :HV-DATE and :HV-DATE2 

只是要确保将第二个变量设置为某个极值,并将其包含在一个宿主变量字段中(这里设置为 ‘9999-12-31’)。注意,只有在使用宿主变量(静态SQL中)或参数标记(动态SQL)时这种方法才奏效。优化工具很聪明,它知道实际上硬编码的 ‘9999-12-31’不会改变逻辑。不过,如果它看到一个变量,在运行时之前它都不知道变量的值,只能在设置值之前完成优化(或准备)。所以,这会哄骗优化工具认为BETWEEN谓词会筛选更多记录行(实际上并非如此)。

尽管不能保证,不过优化工具处理Between谓词和处理区间谓词的做法确实不同,它会采用不同的方式计算谓词的筛选率。开发人员可以大胆尝试,很多情况下这会改变优化路径。

说明:如果SQL来自动态SQL语句,这种方法就不可行了,它只适用于来自静态SQL语句的程序(如COBOL binds或 Javaprepares)。对于动态SQL语句,直到执行时DB2才能知道宿主变量中的具体值是什么。

如果把代码从

 

  1. WHERE HIREDATE  > ? 

改为

 

  1. WHERE HIREDATE  BETWEEN ? and '9999-12-31' 

访问路径不会有任何改变,这是因为,利用硬编码的变量,DB2知道所写的是一个最大值,它会根据这个值完成优化。对于DB2来说,这与区间谓词没有任何差别。

说明:如果是硬编码的变量,与非硬编码变量相比,DB2能了解到更多信息。有时硬编码对于选择访问路径很有好处;不过有时则可能没有任何帮助。

不过,如果数据很不均匀(如本例),对优化工具来说就确实需要硬编码。

另外,DB2 V9特别针对区间偏斜或区间谓词(如Between、Like、>=和<=)中常用的列引入了直方图统计。

posted @ 2013-07-12 09:20  小土_  阅读(300)  评论(0编辑  收藏  举报