什么是更好的?子查询或内部连接十个表?

时间:2011-02-07 12:23:41

标签: sql oracle select

旧系统已经到我们办公室进行一些更改和修复,但它也遇到了性能问题。我们不确切知道这种缓慢的根源是什么。

当我们重构旧代码时,我们发现了几个带有以下模式的SQL查询(查询被简化为例如目的):

SELECT
   (
    SELECT X
    FROM A
    WHERE A.id = TABLE.id
   ) AS COLUMN1,
    (
    SELECT Y
    FROM B
    WHERE B.id = TABLE.id
   ) AS COLUMN1,
   (
    SELECT Z
    FROM C
    WHERE C.id = TABLE.id
   ) AS COLUMN1,
   ...
FROM
    TABLE
WHERE
    TABLE.id = @param;

这些查询会从他们返回的每个列中执行几个内部子查询。

我们计划在以下模式中重写这些查询:

SELECT
    A.X, B.Y, C.Z
FROM
    TABLE
    INNER JOIN A on A.ID = TABLE.ID
    INNER JOIN B on B.ID = TABLE.ID
    INNER JOIN C on C.ID = TABLE.ID
WHERE
    TABLE.id = @param;

通过内部联接,更容易阅读和理解,但它真的更快吗?这是写它们的更好方法吗? 不幸的是,我们重写的第一个没有改善查询时间,它使查询有点慢。

这是我的问题:我们应该重写所有这些查询吗?这些子查询是否是完成这项工作的好方法?他们加快了内联方式吗?

5 个答案:

答案 0 :(得分:15)

如果我正确理解了您的问题,那么您正在开始重写某些SQL语句的操作,因为您认为它们可能存在问题。

我的建议是停下来,先开始确定你的时间目前在哪里。 只有在您发现它与那些标量子选择的查询中之后,并且由于这些标量子选择,您才应该重写它们。 在那之前:开始追踪和检查。

以下是来自OTN的两个主题,用于指导有性能问题的人:

http://forums.oracle.com/forums/thread.jspa?messageID=1812597 http://forums.oracle.com/forums/thread.jspa?threadID=863295

的问候,
罗布。

并且:由于scalar subquery caching,您的原始查询可能比使用连接的重写查询快得多。

答案 1 :(得分:8)

子查询实际上每行都运行一次,而联接则发生在索引上。

使用联接可以提高可读性和可维护性,正如您在问题中已经提到的那样。

答案 2 :(得分:4)

联接将为您提供更好的性能,但我建议您在“优化”查询时查看执行计划。

答案 3 :(得分:2)

作为this answer argues不会影响性能。但是,某些查询优化器可能在JOIN上表现更好,因此您应该在系统上进行一些实验。

现在,对于完全不同的内容:JOIN每个表格到下一个表格可能比使用JOIN TABLE更加美观,并且每当id出现时都会出现错误曾经在其中一个表格中:

SELECT
    A.X, B.Y, C.Z
FROM
    TABLE
    INNER JOIN A on A.ID = TABLE.ID
    INNER JOIN B on A.ID = B.ID
    INNER JOIN C on B.ID = C.ID
WHERE
    TABLE.id = @param;

答案 4 :(得分:0)

这里内部连接更好。原因如下:

1-在主查询中,您正在引用/使用子查询中使用的表中的值。加入就是为了这个目的。您的要求是-“通过连接不同的表来获取一些值,因为无法从一个表中获得这些值”。

当主查询中未引用子查询的列时,应使用

子查询。 喜欢:

select * from emp where deptno in ( select deptno from dept ); 

在这里,您在问-“请给我所有在部门编号 deptno 工作的员工”。您对此部门的 deptno 不太担心。

2-您已经提到过另一个原因是可读性。

3-在性能方面,您不必担心,因为优化器知道该怎么做。

有关更多详细信息,请检查here