相对于另一张表更新表的列时,避免多次选择

时间:2018-11-30 10:22:39

标签: sql oracle query-optimization inner-join

我是SQL查询的新手,但是我需要相对于另一个表的列修改表的列。现在,我可以使用以下查询:

UPDATE table1
SET date1=(
    SELECT last_day(max(date2))+1
    FROM table2
    WHERE id=123
    )
WHERE id=123
  AND date1=to_date('31/12/9999', 'dd/mm/yyyy');

这种结构的问题是,我想将对table1的每一行执行SELECT查询。因此,我尝试创建另一个查询,但是此查询在FROM关键字之后的某个地方存在语法错误:

UPDATE t1
SET t1.date1=last_day(max(t2.date2))+1
FROM table1 t1
INNER JOIN table2 t2
        ON t1.id=t2.id
WHERE t1.id=123
  AND t1.date1=to_date('31/12/9999', 'dd/mm/yyyy');

此外,我什至不知道这个速度是否比第一个更快...

您知道我如何处理此问题吗?

非常感谢!

亲切的问候,

朱利安

2 个答案:

答案 0 :(得分:0)

您编写的第一个代码很好。您不必担心,table1的每一行都不会执行该命令。它将执行以下操作:

  • 它将运行子查询以找到要在UPDATE语句中使用的值,搜索table2,但是正如您已经指出的那样,确切的id来自 桌子,只要有,就应该尽可能快 在该列(我想是主键)上创建了索引
  • 它将运行外部查询,找到要更新的单行。和以前一样,只要在该列上有索引,就应该尽可能快地说出确切的id

总而言之,如果这些ID是唯一的,则子查询和查询都应仅返回一行,并且应尽快执行。如果您认为执行速度不够快(至少花费的时间比证明数据量还长),请检查这些列是否具有唯一值以及它们是否具有唯一索引。

实际上,不管这些问题是什么,如果它们不存在并且这些列具有唯一值,那么最好添加这些索引,因为这将大大提高搜索这些id列的这些表的所有性能。

答案 1 :(得分:0)

请尝试使用MERGE

MERGE INTO ( 
    SELECT id, 
           date1 
      FROM table1 
     WHERE date1 = to_date('31/12/9999', 'dd/mm/yyyy')
       AND id = 123
) t1
USING (
    SELECT id,
           last_day(max(date2))+1 max_date
    FROM table2
    WHERE id=123
    GROUP BY id
) t2 ON (t1.id = t2.id)
WHEN MATCHED THEN
  UPDATE SET t1.date1 = t2.max_date
;