修剪表的存储过程

时间:2013-11-28 05:25:23

标签: database oracle stored-procedures

我正在尝试修剪2列用户NVARCHAR2(32)并在表LT_NAME中记录NVARCHAR(80)。 最初这些列是CHAR,所以我需要修剪它们。 razorsql崩溃,因为该表有40,00,000条记录。有人可以建议在Oracle中使用存储过程来执行此操作吗?

2 个答案:

答案 0 :(得分:1)

使用该数据量可能需要一些时间才能完成update语句。而且,它会生成大量的撤消和重做数据。如果你需要更新整个表,而不是它的部分,CTAS会因为直接路径读取(SGA将被绕过)而很少重做生成,这是完成它的最快方法,但你会花一些时间在重建与表相关的模式对象,约束和授予权限。所以典型的情况是:

  • 使用CTAS创建新表。
  • 如果旧表上有任何索引,则重建新表上的所有索引
  • 如果存在约束,则重新创建约束。
  • 放弃旧桌子
  • 重命名新表
  • 授予适当的权限

设定:

/* 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崩溃。