在 Informix 中使用 ANSI OUTER JOIN 和 OUTER 时查询计划的差异

Posted

技术标签:

【中文标题】在 Informix 中使用 ANSI OUTER JOIN 和 OUTER 时查询计划的差异【英文标题】:Difference in the query plan when using ANSI OUTER JOIN and OUTER in Informix 【发布时间】:2012-01-04 19:30:21 【问题描述】:

使用 ANSI 语法的 Informix 查询性能是否存在差异:

SELECT .. 
  LEFT OUTER JOIN some_table ON (<condition>) 
  LEFT OUTER JOIN some_other_table (<condition_on_some_table>)

和 Informix 特定的 OUTER 语法:

SELECT ... 
  OUTER (some_table, 
   OUTER(some_other_table)) 
WHERE <join_conditions>

谢谢

【问题讨论】:

【参考方案1】:

是的,标准外连接和 Informix 样式外连接的语义存在差异,这不可避免地意味着查询计划存在差异。

一般来说,对任何新的或修改过的代码使用标准表示法 - 为(未更改的)遗留代码保留 Informix 样式的外部连接表示法,并且最好更新它以使用新的连接表示法。

有什么区别?公平的问题 - 很难解释,也更难想出一个好的(似是而非的例子)。基本上,Informix 样式表示法会保留“主要”表(非外部表)中的行,即使存在基于外部联接表中的值的条件会拒绝这些行。

这两个查询产生相同的结果:

SELECT i.*, o.*
  FROM DominantTable AS i, OUTER OuterJoinedTable AS o
 WHERE i.pk_column = o.fk_column;

SELECT i.*, o.*
  FROM DominantTable AS i
  LEFT OUTER JOIN OuterJoinedTable AS o
    ON i.pk_column = o.fk_column;

这两个查询不一定产生相同的结果:

SELECT i.*, o.*
  FROM DominantTable AS i, OUTER OuterJoinedTable AS o
 WHERE i.pk_column = o.fk_column
   AND (o.alt_column IS NULL OR o.alt_column = 1);

SELECT i.*, o.*
  FROM DominantTable AS i
  LEFT OUTER JOIN OuterJoinedTable AS o
    ON i.pk_column = o.fk_column
 WHERE (o.alt_column IS NULL OR o.alt_column = 1);

区别出现在这样的情况下:

DominantTable                              OuterJoinedTable
pk_column   other_column                   fk_column   alt_column
1           twenty                         1           3

标准的 LEFT OUTER JOIN 表示法将产生空集作为结果。 Informix 样式的连接将产生结果:

pk_column   other_column   fk_column   alt_column
1           twenty         null        null

DominantTable 中的数据没有因为主表上的过滤条件而被拒绝,因此它由 Informix 保留。标准联接执行外部联接,然后过滤结果。

【讨论】:

但是,假设我们只使用条件来加入 - 查询是否相同? 阅读我的答案 - 它说了什么?【参考方案2】:

测试并找出或发布两者的执行计划,我们将帮助消化它们。

在其他当前的数据库引擎中,它们将产生相同的执行计划以进行适当的优化。

【讨论】:

其他 DBMS 不实现 Informix 样式的外连接,AFAIK。至少,我很想知道哪些是。

以上是关于在 Informix 中使用 ANSI OUTER JOIN 和 OUTER 时查询计划的差异的主要内容,如果未能解决你的问题,请参考以下文章

如何将此 Informix 嵌套联接转换为 tsql 嵌套联接?

将涉及多个表的左外连接从 Informix 重写为 Oracle

如何在 Hsql 中执行外连接

Oracle 中的连接表(多个外连接)

SQL基础总结——20150730

带有外连接的休眠 HQL 查询