我有一个包含空字段的表。这需要从另一个表填充。虽然从另一个表中获取信息的声明很简单,但我担心更新的性能。
更新由计划每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
表本身有几个索引,包括主键(增量号),用于排序和更新最新记录。
答案 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;
这种方法可以避免更新的需要。