5. 尽量将In子查询重写为Exists子查询

时间:2021-03-27 07:44:56

In和Exists子查询可以生成同样的结果,不过它们的做法截然不同。通常它们的表现各有优劣,这取决于实际的数据分布。例如:

 

  1. SELECT E.EMPNO, E.LASTNAME  
  2. FROM EMP E  
  3. WHERE E.EMPNO IN  
  4.      (SELECT D.MGRNO  
  5.        FROM DEPARTMENT D  
  6.        WHERE D.DEPTNO LIKE 'D%') 

也可以写为:

 

  1. SELECT E.EMPNO, E.LASTNAME  
  2. FROM EMP E  
  3. WHERE EXISTS  
  4.        (SELECT 1  
  5.          FROM DEPARTMENT D  
  6.          WHERE D.MGRNO = E.EMPNO  
  7.            AND D.DEPTNO LIKE 'D%') 

这些相关子查询和非相关子查询有不同的处理优势。现在DB2 V9可能会把子查询转换为它认为更高效的类型,特别是当一个子查询无法转换为联接时,V9就会转换子查询类型。DB2可能选择将子查询转换为联接来处理重复结果。这样一来,在查看DB2 Explain时,可能看不到之前编写的那个子查询,而是会看到一个联接或者另一种类型的子查询,这可能会让人有些困惑。

DB2的做法是根据成本来关联、解除关联或转换为一个联接。IBM Data Studio工具可以显示优化工具完成的查询转换。