【问题标题】:SQL Perfomance : Subselects in joins or direct joins?SQL 性能:连接或直接连接中的子选择?
【发布时间】:2013-11-01 07:42:00
【问题描述】:

我对下表的性能有疑问\

表 A -- 只有 5 个客户 ID(5 行 1 列) 表 B -- 是所有客户及其信息的主库。(100 万行和 500 列)

查询1:-

Select A.*,
       B.Age
from A
left join B
on A.Customer_id = B.Customer_id;

查询 2:-

Select a.*,
       B.Age
from A
left join
(select Customer_id,age from B) C
on A.Customer_id = C.Customer_id;

这里的主要性能问题是因为表 B 中有 500 列。 我觉得第二个查询更好,因为 SQL 在连接期间不必创建一个包含表 B 中所有列的临时表。

如果有错误请告诉我?

【问题讨论】:

  • 在所需列上使用索引使查询运行更快
  • 执行计划会告诉你哪个更好。
  • 如何查看执行计划?

标签: sql performance oracle join


【解决方案1】:

我觉得第二个查询更好,因为 SQL 在连接期间不必创建一个包含表 B 中所有列的临时表。

你可以从解释计划中判断Oracle是否在执行过程中创建了临时表。您还应该考虑如果存在这样一个明显的性能问题,Oracle 内核开发人员是否不会解决它。

碰巧不会有临时表,您的第一个查询也没有问题。几乎从不需要出于性能原因来操作查询 - 编写查询是您所需逻辑的最佳封装。

【讨论】:

【解决方案2】:
CREATE INDEX index_name ON table_b (customer_id)

然后使用

Select a.*,
       B.Age 
from A 
left join (select Customer_id,
                  age 
           from B) C 
        on A.Customer_id = C.Customer_id;

【讨论】:

  • 为什么选择 B 的内联视图?
  • 即通过移除连接操作并将几个单独的查询压缩成一个查询来简化复杂的查询?
  • 我看不出仅仅加入“B”有什么好处,但在这种情况下
【解决方案3】:

500 列相当广泛。

也许您可以创建如下索引:

CREATE INDEX index_name 
          ON table_b (customer_id, 
                      age
                     );

【讨论】:

    【解决方案4】:

    select中的子查询比使用join快(不管是直接join还是sub select)

    select 
       a.*,
       (select b.age 
        from b
        where b.customer_id = a.customer_id)
    from a
    

    注意:

    • 它的行为类似于外连接(如果 a 中不存在来自 b 的 customer_id,则返回年龄中的空字段)
    • 子查询应该只返回来自 a 的每行来自 b 的一行。

    【讨论】:

    • 我希望看到一些支持证据来支持“选择中的子查询比使用连接更快”的断言。在过去,它通常意味着排除某些连接方法,并可能导致性能问题。恐怕我不相信这是真的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-15
    • 2012-02-12
    • 2011-04-20
    • 2011-08-15
    • 1970-01-01
    相关资源
    最近更新 更多