【问题标题】:comparing a column with itself in WHERE clause of oracle SELECT在 oracle SELECT 的 WHERE 子句中将列与自身进行比较
【发布时间】:2011-03-09 12:07:26
【问题描述】:

我有一个多表 SELECT 查询,它将列值与自身进行比较,如下所示:

SELECT * FROM table1 t1,table2 t2
      WHERE t1.col1=t2.col1  --Different tables,So OK.
      AND t1.col1=t1.col1    --Same tables??
      AND t2.col1=t2.col1    --Same tables??

这对我来说似乎是多余的。 我的疑问是,删除它们会对逻辑/性能产生任何影响吗?

提前致谢。

【问题讨论】:

  • 检查是否不仅是同一个表,而且是同一个别名。 (您可以加入同一张桌子两次)。如果是,那很可能是剩菜。

标签: sql database oracle sql-tuning


【解决方案1】:

这似乎是多余的,它唯一的作用是删除这些列中具有 NULL 值的行。在删除这些子句之前确保列不为 NULL。

如果这些列可以为空,您可以安全地将这些行替换为(更易于阅读、更易于维护):

  AND t1.col1 IS NOT NULL
  AND t2.col1 IS NOT NULL


根据 Jeffrey 的评论更新

你说得对,我不知道我自己怎么没看到:连接条件t1.col1=t2.col1 意味着只有连接列不为空的行才会被考虑。因此,子句tx.col1=tx.col1 是完全多余的,可以安全地删除。

【讨论】:

  • 为什么?第一个 t1.col1=t2.col1 已经暗示它们不是 NULL,所以 tx.col1 IS NOT NULL 是多余的。
  • @Jeffrey :你是对的,连接条件已经保证列不为空
【解决方案2】:

在您了解影响之前不要删除它们。如果正如其他人指出的那样,它们对查询没有影响并且可能已被优化,那么将它们留在那里没有害处,但可能删除它们会造成危害。

在你确定没有破坏其他东西之前,不要尝试修复正在工作的东西。

我之所以提到这一点,是因为我们继承了具有这种结构的旧版报告应用程序,大致如下:

where id = id

而且,作为一个明智的人,我放弃了它,却发现数据库引擎并不是唯一使用查询的东西。

它首先通过一个预处理器提取存在于where 子句中的每一列,并确保它们被索引。基本上是一个自动调整数据库。

好吧,想象一下我们在下一次迭代中的惊讶,当用户在 id 字段上进行临时查询时,数据库速度减慢到以前的一小部分 :-)

事实证明,这是以前的支持团队为了确保常见的即席查询也使用索引列而添加的,即使我们的标准查询都没有这样做。

所以,我并不是说你不能做到这一点,只是建议最好先理解它为什么被放进去。

【讨论】:

  • 感谢输入 paxdiablo。到时候我会留着它们的。您所说的报告应用程序是指 Oracle Reports 之类的东西吗?此代码来自 Oracle Reports。
  • 是的,类似 Oracle 报告但不是Oracle 报告。这是一个内部开发的报告工具。
【解决方案3】:
  1. 是的,条件显然是多余的,因为它们是相同的!

    SELECT * FROM table1 t1,table2 t2
    WHERE t1.col1=t2.col1
    
  2. 但您至少需要其中之一。否则,您将拥有笛卡尔连接:table1 中的每一行都将连接到 table2 中的每一行。如果 table1 有 100 行,而 table2 有 1,000 行,则结果查询将返回 100,000 个结果。

    SELECT * FROM table1 t1,table2 t2 --warning!
    

【讨论】:

    猜你喜欢
    • 2023-03-15
    • 2017-09-16
    • 2013-01-05
    • 1970-01-01
    • 1970-01-01
    • 2019-03-28
    • 2020-07-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多