编写高效的子查询

子查询是INSERT、UPDATE、MERGE或DELETE SQL语句的WHERE或HAVING子句中的SELECT语句。 通过了解 Db2 如何处理子查询,当有多种方法可以实现相同的结果时,您就可以在编写给定查询时估计出最佳方法。

关于本任务

开始特定程序编程接口信息。在许多情况下,两个或多个不同的SQL语句可以得到相同的结果,特别是那些包含子查询的语句。 但是,这些语句有不同的访问路径,可能执行方式也不一样。

子查询也可以包含自己的子查询。 这种嵌套子查询可以是相关的,也可以是不相关的。 Db2 对嵌套子查询和非嵌套子查询使用相同的处理技术,并应用相同的优化技术。

对于如何或是否对子查询进行编码,并没有绝对的规定。 Db2 可能会根据优化器的估计将一种子查询转换为另一种子查询。

过程

为了确保包含子查询的SQL语句发挥最佳性能:

请遵循以下一般准则:
  • 如果子查询中的表有高效的索引,那么关联子查询可能是最高效的子查询。
  • 如果子查询中的表没有有效的索引,那么非相关子查询的性能可能会更好。
  • 如果任何父查询中包含多个子查询,请确保子查询以最有效的方式进行排序。

示例

假设MAIN_TABLE有1000行:

SELECT * FROM MAIN_TABLE
  WHERE TYPE IN (subquery 1) AND
        PARTS IN (subquery 2);

假设子查询1和子查询2是相同类型的子查询(相关或非相关),且子查询是第2阶段,则 Db2 将按照子查询在WHERE子句中出现的顺序对其进行评估。 子查询1拒绝10%的总行数,子查询2拒绝80%的总行数:

  • 子查询1中的谓词(称为 P1 )被评估了1000次,子查询2中的谓词(称为 P2 )被评估了900次,总共进行了1900次谓词检查。 然而,如果子查询谓词的顺序颠倒,则 P2 会被计算1000次,而 P1 仅被计算200次,总共进行1200次谓词检查。
  • 如果 P1 和 P2 执行时间相同,那么先编码 P2 再发送 P1 似乎更有效率。 然而,如果 P1 的评估速度比 P2 快100倍,那么最好先编写子查询1的代码。 如果您发现性能下降,请考虑重新排序子查询并监控结果。

    如果您不确定,请在查询中使用相关和非相关的子查询运行EXPLAIN。 通过检查EXPLAIN输出并了解数据分布和SQL语句,您应该能够确定哪种形式更有效。

    这一普遍原则适用于所有类型的谓词。 然而,由于子查询谓词的处理器和I/O密集度可能比其他谓词高数千倍,因此子查询谓词的顺序尤为重要。

无论编码顺序如何, Db2 都会先执行非关联子查询谓词,再执行关联子查询谓词,除非子查询被转换为联接。

结束特定程序编程接口信息。