通过在Oracle中连接多个表来编写有效的更新查询

时间:2017-12-08 14:12:58

标签: sql oracle oracle11g sql-update inner-join

我有一个复杂的要求,即通过连接多个表来查找正确的记录来更新一个表中的某些记录。我编写了以下查询,但它正在运行2.5分钟,这导致我的数据库连接超时。有没有办法通过重写来提高此查询的效率?我也尝试过MERGE方法,这也花了太长时间。我在EVENT_DYNAMIC_ATTRIBUTE表中有超过200万条记录,在EVENT表中有100万条记录,在CATEGORY表中有10万条记录。

UPDATE EVENT_DYNAMIC_ATTRIBUTE eda
SET eda.ATTRIBUTE_VALUE = 'claim',
    eda.LAST_UPDATED_DATE = SYSDATE,
    eda.LAST_UPDATED_BY = 'superUsers'
WHERE eda.DYNAMIC_ATTRIBUTE_NAME_ID=4002
  AND eda.EVENT_ID IN
    (SELECT e.EVENT_ID
     FROM EVENT e
     WHERE e.PRIMARY_CATEGORY_ID IN
         (SELECT CATEGORY_ID
          FROM CATEGORY START WITH CATEGORY_ID = 495984 CONNECT BY PARENT_ID =
          PRIOR CATEGORY_ID));

这是合并查询:

 MERGE INTO EVENT_DYNAMIC_ATTRIBUTE eda
    USING (SELECT DISTINCT e.EVENT_ID FROM (
         SELECT CATEGORY_ID
         FROM CATEGORY 
         START WITH CATEGORY_ID=495984 
         CONNECT BY PARENT_ID =
         PRIOR CATEGORY_ID) CATEGORIES
    INNER JOIN  EVENT E ON e.PRIMARY_CATEGORY_ID = CATEGORY_ID 
    INNER JOIN  EVENT_DYNAMIC_ATTRIBUTE ed on ed.EVENT_ID = E.EVENT_ID) temp 
    ON (eda.EVENT_ID = temp.EVENT_ID ) 
    WHEN MATCHED THEN 
       UPDATE SET eda.ATTRIBUTE_VALUE = 'claim',
                  eda.LAST_UPDATED_DATE = SYSDATE,
                  eda.LAST_UPDATED_BY = 'superUser'
    WHERE eda.DYNAMIC_ATTRIBUTE_NAME_ID=4002

2 个答案:

答案 0 :(得分:0)

您可以尝试类似

的内容
update 
  (
    select
      eda.*
    from
      (select * from event_dynamic_attribute where dynamic_attribute_name_id = 4002) eda,
      (select category_id from category start with category_id = 495984 connect by parent_id = prior category_id) c,
      event e
    where
      e.primary_category_id = c.category_id and
      e.event_id = eda.event_id
  )
set
  attribute_value = 'claim', 
  last_updated_date = sysdate,
  last_updated_by = 'superUsers'

但我怀疑它有帮助。通常,即使在旧硬件上运行,速度也非常低。您应该跟踪这些更新并检查它们的执行,受影响的块等。

首先,我要求你执行

explain plan for <<your update statement text>>;
select * from table(dbms_xplan.display());

并将其结果写入问题。还有一个......在event_dynamic_attribute表中是否有任何触发器?

答案 1 :(得分:-1)

您可以使用WITH CLAUSE

尝试使用因子

http://www.dba-oracle.com/t_sql99_with_clause.htm