Cyn*_*ech 3 sql oracle oracle10g
我有一个流程将日期从GMT转换为澳大利亚东部标准时间.为此,我需要从数据库中选择记录,处理它们然后再保存.
要选择记录,我有以下查询:
SELECT id,
user_id,
event_date,
event,
resource_id,
resource_name
FROM
(SELECT rowid id,
rownum r,
user_id,
event_date,
event,
resource_id,
resource_name
FROM user_activity
ORDER BY rowid)
WHERE r BETWEEN 0 AND 50000
Run Code Online (Sandbox Code Playgroud)
从总共大约中选择一个50000行的块.6000万行.我将它们分开是因为a)Java(写入更新过程的内容)耗尽了很多行的内存(每行都有一个bean对象)和b)我只有4 gig的Oracle临时空间可以播放用.
在这个过程中,我使用rowid来更新记录(所以我有一个唯一的值)和rownum来选择块.然后我在迭代中调用此查询,选择接下来的50000条记录,直到没有剩余(java程序控制它).
我得到的问题是,我仍然在使用此查询耗尽Oracle临时空间.我的DBA告诉我,不能授予更多临时空间,因此必须找到另一种方法.
我已经尝试用子视图替换子查询(我认为使用带排序的所有临时空间),但是使用视图的解释计划与原始查询之一相同.
是否有不同/更好的方法来实现这一点而不会遇到内存/温度空间问题?我假设更新查询更新日期(而不是java程序)会遇到使用临时空间可用的相同问题?
非常感谢您对此的帮助.
更新
我按照下面的建议走了pl/sql块的路径:
declare
cursor c is select event_date from user_activity for update;
begin
for t_row in c loop
update user_activity
set event_date = t_row.event_date + 10/24 where current of c;
commit;
end loop;
end;
Run Code Online (Sandbox Code Playgroud)
但是,我的撤消空间已经用完了.我的印象是,如果在每次更新后进行提交,则对撤消空间的需求很小.这个假设我不正确吗?
单个更新可能不会遇到同样的问题,并且可能会快几个数量级.由于排序,只需要大量的临时表空间.虽然如果您的DBA对临时表空间如此吝啬,您可能最终会耗尽UNDO空间或其他内容.(看看ALL_SEGMENTS,你的桌子有多大?)
但是如果你真的必须使用这种方法,也许你可以使用过滤器而不是命令.创建1200个桶并一次处理一个:
where ora_hash(rowid, 1200) = 1
where ora_hash(rowid, 1200) = 2
...
Run Code Online (Sandbox Code Playgroud)
但这将是可怕的,非常缓慢.如果价值在整个过程中途发生变化,会发生什么?单个SQL语句几乎肯定是执行此操作的最佳方式.
归档时间: |
|
查看次数: |
8581 次 |
最近记录: |