【问题标题】:NOOB query on select statement选择语句上的 NOOB 查询
【发布时间】:2014-10-16 17:59:39
【问题描述】:

我有以下表格和数据。

错误

bug_id creator category_id change_request_id
1       john        101         123
2       mark        124         124
3       mark        139         135
4       shane       167         148
6       logan       278         234

类别

id  owner category_name
101 mark    abc
124 john    def
139 mark    ghi
167 mark    jkl 
278 mark    mno

Change_request

id  creator
123 mark
124 mark
135 mark
148 john
234 mark

我需要从 bug 表中提取所有 bug,其 creator 字段值为 john 或类别所有者为 john(只不过是类别表的所有者字段)或 change_request“创建者”为 john。

我写了一个简单的选择语句来实现这个

SELECT bug_id
  FROM bugs
     ,category
     ,change_request
 WHERE ((bugs.creator = 'john'
              )
           OR ((bugs.category_id = category.id
                     )
                 AND (category.owner = 'john'
                     )
              )
           OR ((bugs.change_request_id = change_request.id
                     )
                 AND (change_request.creator = 'john'
                     )
              )
       );

但是当我使用上面的查询时,执行时间太长了。我所有的表列都被正确索引。是否有优化查询来解决我的目的?

【问题讨论】:

  • 10g? 11克?是哪一个?
  • 避免使用不推荐使用的语法,使用标准的JOIN 语法会更干净,更容易排除故障。

标签: sql oracle oracle11g oracle10g


【解决方案1】:

查询优化器可以更轻松地处理这个问题:

SELECT bug_id
  FROM bugs
    JOIN category ON bugs.category_id = category.id
    JOIN change_request ON bugs.change_request_id = change_request.id
WHERE (bugs.creator = 'john') 
  OR (category.owner = 'john')
  OR (change_request.creator = 'john');

您可以使用逗号运算符编写相同的内容,并且只使用 WHERE 谓词,但生成的 where 子句与您的不同(尽管它的计算方式相同)。

【讨论】:

  • 非常感谢您的回答。投票并标记为答案
【解决方案2】:

添加到约翰·博林格的回答中,为什么花费太长时间的原因是因为笛卡尔在您的 WHERE 子句中加入了结果。 WHERE 子句中的 OR 使连接条件不是强制性的。

例如,如果bugs.creatorJOHN,您的其他谓词将被忽略,从而导致JOHN 记录与category 中的ALL 记录结合在一起和change_request 表。

John 的查询将消除这种不良影响,因为它正确地将连接条件和过滤谓词放在了它们所属的位置。

【讨论】:

  • 感谢您的解释。投票
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-01-03
  • 1970-01-01
  • 2020-07-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-22
相关资源
最近更新 更多