Одной из возможных причин низкой производительности является цепочка строк. Все ваши строки изначально имеют столбцы C3 и C4 null, а затем вы обновляете их все, чтобы иметь значение. Новые данные не будут вписываться в существующие блоки, поэтому Oracle должен привязать строки к новым блокам.
Если вы знаете заранее, что вы будете делать это, вы можете предварительно выделить достаточное количество свободного пространства, как это:
CREATE TABLE J_TEST
(
ID NUMBER(10) PRIMARY KEY,
C1 VARCHAR2(50 BYTE),
C2 VARCHAR2(250 BYTE),
C3 NUMBER(5),
C4 NUMBER(10)
) PCTFREE 40;
... где PCTFREE указывает процент пространства, чтобы сохранить свободный обновлений. Значение по умолчанию - 10, чего недостаточно для этого примера, где строки более или менее удваиваются по размеру (от средней длины от 8 до 16 байт в соответствии с моим db).
Этот тест показывает разницу он делает:
SQL> CREATE TABLE J_TEST
2 (
3 ID NUMBER(10) PRIMARY KEY,
4 C1 VARCHAR2(50 BYTE),
5 C2 VARCHAR2(250 BYTE),
6 C3 NUMBER(5),
7 C4 NUMBER(10)
8 );
Table created.
SQL> insert into j_test (id)
2 select rownum
3 from transactions
4 where rownum < 100000;
99999 rows created.
SQL> update j_test
2 set C3 = 1,
3 C2 = 'NEU'
4/
99999 rows updated.
Elapsed: 00:01:41.60
SQL> analyze table j_test compute statistics;
Table analyzed.
SQL> select blocks, chain_cnt from user_tables where table_name='J_TEST';
BLOCKS CHAIN_CNT
---------- ----------
694 82034
SQL> drop table j_test;
Table dropped.
SQL> CREATE TABLE J_TEST
2 (
3 ID NUMBER(10) PRIMARY KEY,
4 C1 VARCHAR2(50 BYTE),
5 C2 VARCHAR2(250 BYTE),
6 C3 NUMBER(5),
7 C4 NUMBER(10)
8 ) PCTFREE 40;
Table created.
SQL> insert into j_test (id)
2 select rownum
3 from transactions
4 where rownum < 100000;
99999 rows created.
SQL> update j_test
2 set C3 = 1,
3 C2 = 'NEU'
4/
99999 rows updated.
Elapsed: 00:00:27.74
SQL> analyze table j_test compute statistics;
Table analyzed.
SQL> select blocks, chain_cnt from user_tables where table_name='J_TEST';
BLOCKS CHAIN_CNT
---------- ----------
232 0
Как вы можете видеть, с PCTFREE 40 обновление занимает 27 секунд, а не 81 секунд, а результирующая таблица потребляет 232 блоков, без скованных строк вместо 694 блоков с 82034 цепочками!
«C4 ЧИСЛО (10)» по сравнению с «SET C4 =« NEU »заставляет меня почесывать голову. Это намерение или я не хватает захватывающей функции Oracle? – Tomalak 2008-11-17 16:44:51
Tomalak, такой же мысль здесь. – 2008-11-17 16:59:12