更新NULL字段与最新记录

时间:2014-04-22 10:13:14

标签: sql oracle

我有一个包含空字段的表。这需要从另一个表填充。虽然从另一个表中获取信息的声明很简单,但我担心更新的性能。

更新由计划每30分钟运行一次的脚本完成。

哪个更好:

  • 使用where字段更新为空语句

    UPDATE table1 SET freefield=(SELECT name FROM table2 WHERE table1.keyfield=table2.field) WHERE freefield IS NULL;

  • 使用仅更新最后X条记录的语句进行更新

    UPDATE table1 SET freefield=(SELECT name FROM table2 WHERE table1.keyfield=table2.field) WHERE ROWID IN ( SELECT ROWID FROM ( SELECT keyfield FROM table1 ORDER BY keyfield DESC ) WHERE ROWNUM < 300 );

table1.keyfield和table2.field被索引并具有primary / fk关系。 table1.freefield和table2.name未编入索引,是文本字段。

目前该表只有大约10万条记录,但会大幅增长。基本上我要问的是,它需要更长的时间来搜索表中的空字段,或者它要订购它并仅使用指定的最新数字。

最终计划是实施一个触发器,以便记录在创建时正确更新,但在我们的软件的下一个版本出于质量控制原因等之前无法实现。

数据库是Oracle 10.2.0.5

表本身有几个索引,包括主键(增量号),用于排序和更新最新记录。

2 个答案:

答案 0 :(得分:3)

您可以使用基于函数的索引来仅识别具有NULL的行。 这样的指数会非常小。

create index index_name 
    on owner.table_name(case when your_column is null then 'x' end) compress 1;

要更新您要执行的列:

update owner.table_name
   set your_column = <your-logic-here>
 where (case when your_column is null then 'x' end) = 'x';

在初始问题更改后进行修改: 您的两个选项不会给出相同的结果。只有选项1才能实现更新所有缺失的freefield&#34;

的要求。

如果每30分钟获得超过300次插入,并不是所有这些插入都会使用选项2更新。此外,您已经引入了一个不必要的依赖关系,将来可能会或可能不会生效:每当记录R1.keyfield时&GT;记录R2.keyfield,然后记录R1比R2更新。

答案 1 :(得分:2)

最好先执行,更新字段为NULL的位置。意图似乎是保留表格,因此唯一的NULL值是最近的值。我强烈主张编写符合您意图的代码。

如果您只尝试更新最后的XX条记录,那么您有条件可能会遗漏某些NULL值:

  • 在时间段内插入的记录超出预期。
  • 由于某种原因,您错过了一个或多个更新周期。

如果您担心性能问题,请在字段上添加索引以便于查找所需的记录。

最后,如果更新很简单,那么您可以考虑仅使用视图并通过视图进行所有访问:

create view v_table as
    select coalesce(col, 0) as ReplaceTheNull
    from table;

这种方法可以避免更新的需要。