我正在尝试修剪2列用户NVARCHAR2(32)并在表LT_NAME中记录NVARCHAR(80)。 最初这些列是CHAR,所以我需要修剪它们。 razorsql崩溃,因为该表有40,00,000条记录。有人可以建议在Oracle中使用存储过程来执行此操作吗?
答案 0 :(得分:1)
使用该数据量可能需要一些时间才能完成update
语句。而且,它会生成大量的撤消和重做数据。如果你需要更新整个表,而不是它的部分,CTAS会因为直接路径读取(SGA将被绕过)而很少重做生成,这是完成它的最快方法,但你会花一些时间在重建与表相关的模式对象,约束和授予权限。所以典型的情况是:
设定:
/* This small utility package is needed to simply display the size of redo */
SQL> create or replace package PKG as
2 g_redo number := 0;
3 procedure initialize;
4 procedure show_redo;
5 end;
6 /
Package created
SQL> create or replace package body pkg as
2 procedure initialize is
3 begin
4 select ms.value
5 into pkg.g_redo
6 from v$statname sn
7 join v$mystat ms
8 on (ms.statistic# = sn.statistic#)
9 where sn.name = 'redo size';
10 end;
11
12 procedure show_redo is
13 l_redo number;
14 begin
15 select ( ms.value - pkg.g_redo ) / 1024
16 into l_redo
17 from v$statname sn
18 join v$mystat ms
19 on (ms.statistic# = sn.statistic#)
20 where sn.name = 'redo size';
21 dbms_output.put_line('redo size: ' || to_char(l_redo) || ' KB');
22 end;
23 end;
24 /
Package body created
在此示例中,测试表t1
仅包含1 200 001行。
SQL> select count(*) as cnt
2 from t1;
cnt
----------
1200001
以下是update
1 200 001行所花费的时间和重做次数:
SQL> set serveroutput on;
SQL> set timing on;
SQL> set autotrace off;
SQL> set feedback off;
SQL> exec pkg.initialize;
Elapsed: 00:00:00.00
SQL> update t1
2 set col1 = trim(col1)
3 , col2 = trim(col2);
Elapsed: 00:00:28.67
SQL> exec pkg.show_redo;
redo size: 421024.28515625 KB
Elapsed: 00:00:00.00
这是多长时间和重做СTAS:
SQL> exec pkg.initialize;
Elapsed: 00:00:00.00
SQL> create table t2(col1, col2) as
2 select trim(col1)
3 , trim(col2)
4 from t1;
Elapsed: 00:00:01.85
SQL> exec pkg.show_redo;
redo size: 163 KB
当然,您的时间和重做大小会有所不同,但CTAS将比常规update
语句花费更少的时间和重做。
答案 1 :(得分:0)
对于四千万条记录应用UPDATE将花费很长时间,无论你如何做。
实际查询非常简单:
update your_table
set user = rtrim(user)
, record = rtrim(record)
/
这应该在SQL * Plus中运行,前提是您的DBA已经为具有这种大小的表的数据库充分配置了UNDO表空间。
您应该在开始之前锁定整个表,或者如果这是一个选项,则以受限模式启动数据库。这是为了确保您可以一举更新整个表格。
如果您觉得这不能回答您的问题,请编辑它以提供更多详细信息,给出您正在运行的约束,并解释为什么RazorSQL崩溃。