Sql 正确的查询设计?交叉联接驱动即席报告接口
我希望一些更有经验的数据库/dwh开发人员或DBA能够参与其中: 我的团队将OBIE用作前端工具,以推动我们的业务部门进行即席报告 当生成相对较小的集合时,会有很多延迟。我们需要1小时才能制作出5万张唱片 我查看了其中一个以这种方式运行的查询,惊讶地发现所有被引用的表都被交叉连接,然后过滤器被应用到Sql 正确的查询设计?交叉联接驱动即席报告接口,sql,database,oracle,database-design,obiee,Sql,Database,Oracle,Database Design,Obiee,我希望一些更有经验的数据库/dwh开发人员或DBA能够参与其中: 我的团队将OBIE用作前端工具,以推动我们的业务部门进行即席报告 当生成相对较小的集合时,会有很多延迟。我们需要1小时才能制作出5万张唱片 我查看了其中一个以这种方式运行的查询,惊讶地发现所有被引用的表都被交叉连接,然后过滤器被应用到WHERE子句中 因此,为了举例说明,查询通常如下所示: SELECT ... FROM tbl1 ,tbl2 ,tbl3 ,tbl4 WHERE tbl1.col1 = tb
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
而不是像这样:
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上下文中的答案时才回答)?不幸的是,我没有管理员权限对查询的两个不同版本运行跟踪
是否有理由以第一种方式设置查询,与OBIEE接口的工作方式有关?请记住,查询是用户将属性从“属性库”拖放到沙箱中的结果。选择属性的任何组合都应该生成输出(如果数据存在)。属性来自许多不同的表。我没有设计基于这种特殊属性选择生成SQL的mecahnism的经验,因此我不知道第一个示例中的查询设计是否需要为这种报告工具提供服务。别担心,从历史上看,Oracle对内部联接使用了第一种表示法,但后来采用了ANSI SQL标准 性能方面的结果和返回的记录集完全相同,隐式的“逗号”连接不是交叉结果集,而是有效地集成了
WHERE
过滤器。如果您对此有疑问,请对这两个查询运行EXPLAIN-SELECT
命令,您将看到预测的算法是相同的
展开此答案,您可能会注意到将来使用类似符号(+)代替外部联接。在这种情况下,这个答案也是正确的
当两个符号(隐式连接和显式连接)在同一个查询中混合时,真正的问题就出现了。这将是自找麻烦,但我怀疑你在欧比身上找到这样的情况 这些是内部联接,而不是交叉联接,它们只是使用旧的语法,而不是您所期望的ANSI 大多数联接查询在FROM子句或WHERE子句中至少包含一个联接条件。() 对于一个简单的查询,例如在您的示例中,执行应该完全相同 在您设置外部联接(在业务模型联接中)的地方,您将看到OBI生成一个查询,其中内部联接在Where子句中进行,外部联接在FROM语句中完成——这只是为了让调试变得非常困难
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
很好,谢谢你的信息+1.我会把这个打开一段时间,以防万一其他人有什么要添加的。Oracle不鼓励使用
(+)
操作符。Oracle建议使用显式的外部联接
运算符,而不是专有的(+)
。将尝试解释选择
-谢谢您的帮助。@a_horse_,没有名称:谢谢!我一直想知道甲骨文的偏好是什么。你有这方面的信息来源吗?@wolφi::“Oracle建议你使用FROM子句外部连接语法,而不是Oracle连接运算符”这两个查询变量可能会产生相同的执行计划,如果你想找到瓶颈,你无论如何都应该检查它。交叉帖子:谢谢你的信息,+1。你是对的,我看到了Oracle特定的内部联接和ANSI LOJs的组合,对此感到非常震惊。很高兴澄清这一点。谢谢。我不确定你什么时候找到这个查询,但这是有史以来最糟糕的事情。看:@Sebas我没说这是好的。这就是欧比的作品。已经5年多了,所以甲骨文似乎并不急于改变它。