2013-11-28 7 views
0

Я пытаюсь обрезать 2 столбца пользователя NVARCHAR2 (32) и записывать NVARCHAR (80) в таблицу LT_NAME. Первоначально эти столбцы были CHAR, поэтому мне нужно их обрезать. razorsql падает, поскольку таблица содержит 40 000 000 записей. Может ли кто-нибудь предложить хранимую процедуру в Oracle для этого?Сохраненная процедура обрезки таблицы

+0

Пожалуйста, сообщите нам еще – APC

ответ

0

Применение UPDATE к сорока миллионам записей займет много времени, независимо от того, как вы это делаете.

Фактический запрос достаточно прост:

update your_table 
set user = rtrim(user) 
    , record = rtrim(record) 
/

Это должно работать в SQL * Plus, если администратор базы данных имеет провизию UNDO табличные достаточно для базы данных с таблицами такого размера.

Перед тем, как начать, вы должны заблокировать всю таблицу или запустить базу данных в ограниченном режиме, если это опция. Это делается для того, чтобы вы могли обновить всю таблицу одним махом.


Если вы чувствуете, что это не отвечает на вопрос, пожалуйста, измените его, чтобы предоставить больше деталей, что дает ограничения вы действуете под и, возможно, объясняет, почему RazorSQL разбился.

1

С этим объемом данных может потребоваться некоторое время для завершения заявления update. Более того, он будет генерировать большое количество данных отмены и повтора. если вам нужно обновить всю таблицу, а не ее часть, CTAS будет, из-за прямого чтения пути (SGA будет обойден) и небольшой генерации повтора, самый быстрый способ сделать это, но вы потратите некоторое время на восстановление объектов схемы, связанных с таблицами, ограничений и предоставления привилегий. Таким образом, типичным сценарием будет:

  • Создайте новую таблицу, используя CTAS.
  • Восстановить все индексы на новой таблице, если бы были какие-то индексы на старом
  • Восстановить ограничения, если они есть, триггеры.
  • падения старый стол
  • Переименовать новую таблицу
  • Grant соответствующие привилегии

Установка:

/* 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 

Вот сколько времени и Redo С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.

Смежные вопросы