【问题标题】:Update statement is too slow with Correlated subquery相关子查询的更新语句太慢
【发布时间】:2018-06-25 06:51:19
【问题描述】:

我正在使用下面的更新语句,它太慢了(大约需要 10-12 秒)

UPDATE temp_final t
   SET name = (
        SELECT DISTINCT(nm.name)
          FROM table_name nm,
               temp_final fn
         WHERE nm.id       = fn.senid
           AND fn.senid    = t.senid
           AND fn.rowgroup = t.rowgroup
           AND fn.mid      = t.mid
           AND fn.sid      = t.sid
           AND fn.pid      = t.pid
           AND fn.reid     = t.reid
           AND fn.retype   = t.retype
        )
 WHERE t.reid   = n_reid
   AND t.retype = n_retype
   AND t.sid    = c_sid
   AND t.pid    = n_pid;    

temp_final 表的列没有索引,因为该表包含大量数据更新。我认为,我无法将相关子查询转换为加入,因为它使用不同的子句。此查询的计划给出以下结果:

OPERATION                              OBJECT        CARDINALITY     COST
- UPDATE STATEMENT                                       1925        337046      
  - UPDATE                             temp_final 
    -TABLE ACCESS(FULL)                temp_final        1925        171
      - Filter Predicates
        - AND
          -T.SID='123'
          -T.PID=21
          -T.REID=9
          -T.RETYPE=1
    -SORT(UNIQUE)                                         1          175
      - NESTED LOOPS                                      1          174 
         -TABLE ACCESS(BY INDEX ROWID)  TABLE_NAME        1           2
           -INDEX(UNIQUE SCAN)          NAME_PK           1           1  
             -ACCESS PREDICATES
               NM.ID=:B1
         -TABLE ACCESS(FULL)            temp_final        1           172
           - Filter Predicates
             - AND
               -fn.mid=:B1
               -fn.senid=:B2
               -fn.sid =:B3
               -fn.rowgroup =:B4
               -fn.pid=:B5
               -fn.reid=:B6
               -fn.retype=:B7
               -nm.id = fn.senid

表 temp_final 包含大约 8k 条记录,表 table_name 包含大约 2 条 lac 记录

请告诉我如何提高此查询的性能?

问候

【问题讨论】:

  • fn.SenId 是 temp_final 表的唯一键。 table_name 中 name 和 id 的组合也是唯一的吗?
  • 您好 Vishad,fn.SenId 不是 temp_final 表的唯一键,并且由于 id 是 table_name 的主键,因此 id 和 name 始终是唯一组合。但是在这种情况下它有什么帮助呢?谢谢

标签: sql oracle performance correlated-subquery


【解决方案1】:

我不完全了解您的自我加入。这句话还不够:

UPDATE temp_final t
   SET name = (
        SELECT nm.name
          FROM table_name nm
         WHERE nm.id       = t.senid
        )
 WHERE t.reid   = n_reid
   AND t.retype = n_retype
   AND t.sid    = c_sid
   AND t.pid    = n_pid;    

【讨论】:

  • 您好,感谢您的回复。它是一个遗留系统,原始查询也有不同。如果子查询返回多于一行,它将失败。尽管我已经用一组测试数据测试了您的查询,并且它更新了与原始查询相同的行数。
  • 如果 id 是 table_name 的主键,则不需要 DISTINCT。小版本比原来的版本快吗?
  • 是的,它更快。我将使用 10-15 个以上的测试集测试较小的查询,以便更安全并接受您的答案。非常感谢。 @wolφi,我有一个非常庞大的程序,它的性能很差,我需要改进它,你能推荐任何书或材料吗?请注意,我在数据库方面工作不多。谢谢。
  • 我从 Tom Kyte 的两本关于 architecturedesign 的书中学到的最多。 Database Concepts 非常棒,值得一读(没有其他人这样做,所以你会有优势:-)
  • 感谢 wolφi 的建议,我会检查一下。
猜你喜欢
  • 2013-11-24
  • 1970-01-01
  • 1970-01-01
  • 2016-11-14
  • 1970-01-01
  • 1970-01-01
  • 2011-11-05
  • 2012-07-08
  • 1970-01-01
相关资源
最近更新 更多