表现:子查询或加入

时间:2010-05-20 06:54:54

标签: sql oracle

我对子查询的性能/加入另一个表有一个小问题

INSERT
INTO Original.Person
  (
    PID, Name, Surname, SID
  )
  (
    SELECT ma.PID_new , TBL.Name , ma.Surname, TBL.SID 
    FROM Copy.Person TBL , original.MATabelle MA
    WHERE TBL.PID         = p_PID_old
      AND TBL.PID         = MA.PID_old
  );

这是我的SQL,现在这个东西运行大约100万次或更多。 我的问题是什么会更快?

  • 如果我将TBL.SID更改为(Select new from helptable where old = tbl.sid

OR

  • 如果我将“HelpTable”添加到from并加入where

EDIT1
好吧,这个脚本的运行次数和其他人一样多。

我的程序有2个模块,一个填充MaTabelle,另一个模块传输数据。该程序确实将2个数据库合并在一起,因此有时会使用相同的密钥 现在我正在研究一种没有重复密钥存在的解决方案。

我的解决方案是制作一个'HelpTable'。密钥(SID)的所有者生成一个新密钥并将其写入“HelpTable”。使用此密钥的所有其他表都可以从“HelpTable”中读取它。

EDIT2
我脑子里想到了一些东西:
如果一个表作为一个可以为null的键(未链接的外键) 然后这不适用于from或?

4 个答案:

答案 0 :(得分:7)

现代RDBM(包括Oracle)将大多数联接和子查询优化为同一个执行计划。

因此,我会继续以最简单的方式编写查询,并专注于确保您已完全优化索引。

如果您提供最终查询和数据库架构,我们可能会提供详细的建议,包括有关潜在锁定问题的信息。

修改

以下是一些适用于您的查询的一般提示:

  • 对于联接,请确保您要加入的列上有索引。确保将索引应用于两个表中的联接列。你可能认为你只需要一个方向的索引,但是你应该对它们进行索引,因为有时数据库会确定最好以相反的方向加入。
  • 对于WHERE子句,请确保在WHERE中提到的列上有索引。
  • 要插入多行,最好将它们全部插入到一个查询中。
  • 要在具有聚簇索引的表上插入,最好插入聚簇索引的增量值,以便将新行附加到数据的末尾。这样可以避免重建索引,并且通常可以避免对现有记录进行锁定,从而减慢对现有行的SELECT查询速度。基本上,插入对系统的其他用户来说不那么痛苦。

答案 1 :(得分:3)

加入比子查询快得多

答案 2 :(得分:2)

子查询和连接之间的主要区别是 当我们必须从大量表中检索数据时,子查询更快。因为加入更多表变得很繁琐。 当我们有更少的表时,join更快地从数据库中检索数据。

此外,这个joins vs subquery可以为您提供更多信息

答案 3 :(得分:0)

我不会专注于是否使用连接或子查询,而是专注于对特定插入语句执行1,000,000次执行的必要性。特别是正如Oracle的优化者 - 正如Marcus Adams已经指出的那样 - 将优化和重写您的报表,使其成为最佳形式。

你只用几行填充MaTabelle 1,000,000次并发出声明吗?如果是,那么答案就是一次性完成。您能否多次提供有关正在执行此语句的进程的更多信息?

编辑:您指出此插入语句是针对每个人执行的。在这种情况下,建议首先填充MATabelle,然后执行一次:

INSERT 
INTO Original.Person 
  ( 
    PID, Name, Surname, SID 
  ) 
  ( 
    SELECT ma.PID_new , TBL.Name , ma.Surname, TBL.SID  
    FROM Copy.Person TBL , original.MATabelle MA 
    WHERE TBL.PID         = MA.PID_old 
  );

此致 罗布。