正确的查询设计?交叉连接驱动ad-hoc报告界面

时间:2014-11-17 20:36:29

标签: sql database oracle database-design obiee

我希望一些经验丰富的数据库/ dwh开发人员或DBA可以在这一点上权衡:

我的团队正在使用OBIEE作为前端工具来推动我们的业务部门进行临时报告。

生成相对较小的集合时会有很多延迟。我们正面临约1小时的时间来制作约5万条记录。

我查看了其中一个以这种方式运行的查询,我惊讶地发现所有被引用的表都是交叉连接的,然后在WHERE子句中应用了过滤器。

因此,为了说明,查询往往看起来像这样:

SELECT ...
FROM tbl1
    ,tbl2
    ,tbl3
    ,tbl4
WHERE tbl1.col1 = tbl2.col1
and tbl3.col2 = tbl2.col2
and tbl4.col3 = tbl3.col3

而不是像这样:

SELECT ...
FROM tbl1
INNER JOIN tbl2
    ON tbl1.col1 = tbl2.col1
INNER JOIN tbl3
    ON tbl3.col2 = tbl2.col2
INNER JOIN tbl4
    ON tbl4.col3 = tbl3.col3

现在,根据我对查询操作顺序的了解,FROM子句在WHERE子句之前执行,因此第一个示例的执行速度比后一个示例慢得多。我是否正确(只有在Oracle DB的背景下知道答案时才能回答)?不幸的是,我没有管理员权限来对2个不同版本的查询运行跟踪。

是否有理由以第一种方式设置查询,与OBIEE接口的工作方式有关?请记住,查询是用户将属性拖放到沙箱中的结果,来自属性的“库”。选择任何属性组合应该生成输出(如果数据存在)。属性来自许多不同的表。我没有任何设计基于这种ad-hoc属性选择生成SQL的mecahnism的经验,所以我不知道第一个例子中的查询设计是否需要为这种报告工具提供服务。

2 个答案:

答案 0 :(得分:4)

不用担心,历史上Oracle使用内连接的第一种表示法,但后来采用了ANSI SQL标准。

在性能和返回记录集方面的结果完全相同,隐含的逗号'联接不是跨越结果集,而是有效地集成WHERE过滤器。如果您对此表示怀疑,请对两个查询运行EXPLAIN SELECT命令,您将看到预测的算法将是相同的。


扩展此答案,您可能会注意到将来使用类似符号(+)代替外连接。在这种情况下,这个答案也是正确的。

当同一个查询中混合使用两种符号(隐式和显式联接)时,会出现真正的问题。这将是一个很大的麻烦,但我怀疑你在OBIEE中发现了这样的情况。

答案 1 :(得分:1)

这些是内连接,而不是交叉连接,它们只是使用旧语法来执行它,而不是像您期望的那样使用ANSI。

  

大多数连接查询在FROM子句或WHERE子句中至少包含一个连接条件。 (Oracle Documentation

对于简单的查询,例如在您的示例中,执行应该完全相同。

在您设置外连接的位置(在业务模型连接中),您将看到OBI生成一个查询,其中内部连接在WHERE子句中进行,外连接在FROM语句中完成ANSI - 只是为了使事情变得真实难以调试!

SELECT ...
FROM tbl1
    ,tbl2
    ,tbl3 left outer join
         tbl4 on tbl3.col1 = tbl4.col2
WHERE tbl1.col1 = tbl2.col1
and tbl3.col2 = tbl2.col2
and tbl4.col3 = tbl3.col3