我们正在处理Oracle项目中一个非常慢的更新语句.
这是一个重写问题的小脚本:
drop table j_test;
CREATE TABLE J_TEST
(
ID NUMBER(10) PRIMARY KEY,
C1 VARCHAR2(50 BYTE),
C2 VARCHAR2(250 BYTE),
C3 NUMBER(5),
C4 NUMBER(10)
);
-- just insert a bunch of rows
insert into j_test (id)
select rownum
from <dummy_table>
where rownum < 100000;
-- this is the statement that runs forever (longer than my patience allows)
update j_test
set C3 = 1,
C1 = 'NEU';
Run Code Online (Sandbox Code Playgroud)
在某些环境中,Update-Statement只需要大约20秒,其中一些语句运行几分钟.使用更多行时,问题会变得更糟.
我们不知道是什么导致了这种行为,并希望在提出解决方案之前了解正在发生的事情.
有什么想法和建议吗?谢谢托尔斯滕
Ton*_*ews 12
行为不佳的一个可能原因是行链.您的所有行最初都有列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;
Run Code Online (Sandbox Code Playgroud)
...... PCTFREE指定保留更新空间的百分比.默认值为10,这对于此示例来说是不够的,其中行的大小或多或少加倍(根据我的db,平均长度为8到16个字节).
该测试显示了它的不同之处:
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
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,使用PCTFREE 40更新需要27秒而不是81秒,并且生成的表使用232个没有链接行的块而不是带有82034个链接行的694个块!
| 归档时间: |
|
| 查看次数: |
6745 次 |
| 最近记录: |