最近帮一个客户做数据迁移测试,数据库版本的10.2.0.4.0,操作系统是AIX到Linux,采用EXPDP/IMPDP方式进行全库导出和导入。
客户的数据库有3.6T,导出时间花了30小时,但是导入却花了120小时,这个很不正常。因为目标数据库的I/O效率比源数据库的I/O效率要高,导入过程中发现导入表数据的时候很快,而后来创建索引的时间特别长,占了80%的时间。通过AWR报告分析,竟然发现在导入过程中运行了下面语句:
ANALYZE TABLE "XXX."XXXX" COMPUTE STATISTICS;
被分析的这个表450G,分析了40小时的时间,这个让人摸不到头脑,后来查看了大量资料,发现这是Oracle10g的一个bug,就是在用expdp导出过程中,如果某个表包含函数索引,则在导入过着中会到该表进行分析,通过形成导入脚本验证了这个说法。下面是验证过程:
Sqlplus system/****
SQL> create table test (id number, name varchar2(30)) tablespace users;
SQL>insert into test values (1,’A’);
SQL>COMMIT;
Expdp system/******** directory=expdir dumpfile=test01.dmp tables=test
Impdp system/******** directory=expdir dumpfile=test01.dmp sqlfile=test01.sql
查看test01.sql的内容
没有发现 表分析语句
创建行数索引
SQL>create index idx_test on test(upper(name)) tablespace users;
重新导出导入形成导入脚本,发现脚本中包含下面内容
CREATE INDEX "SYSTEM"."IDX_FUN_1" ON "SYSTEM"."TEST" (UPPER("NAME"))
PCTFREE 10 INITRANS 2 MAXTRANS 255
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "SYSTEM" PARALLEL 1 ;
ALTER INDEX "SYSTEM"."IDX_FUN_1" NOPARALLEL;
-- new object type path is: TABLE_EXPORT/TABLE/INDEX/STATISTICS/FUNCTIONAL_AND_BITMAP/INDEX_STATISTICS
DECLARE IND_NAME VARCHAR2(60);
IND_OWNER VARCHAR2(60);
BEGIN
DELETE FROM "SYS"."IMPDP_STATS";
IND_NAME := 'IDX_FUN_1'; IND_OWNER := 'SYSTEM';
INSERT INTO "SYS"."IMPDP_STATS" (type, version, flags, c1, c2, c3, c5,
n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12, d1)
VALUES ('I', 4, 2, IND_NAME, NULL, NULL, 'SYSTEM', 10, 1, 10, 1, 1, 1, 0, 10, NULL, NULL, NULL, NULL, TO_DATE('2015-11-25 16:02:35', 'YYYY-MM-DD:HH24:MI:SS'));
DBMS_STATS.IMPORT_INDEX_STATS( '"' || ind_owner || '"', '"' || ind_name || '"', NULL, '"IMPDP_STATS"', NULL, '"SYS"');
DELETE FROM "SYS"."IMPDP_STATS";
END;
/
-- new object type path is: TABLE_EXPORT/TABLE/STATISTICS/TABLE_STATISTICS
ANALYZE TABLE "SYSTEM"."TEST" COMPUTE STATISTICS;
重新导出,忽略统计信息
Expdp system/******** directory=expdir dumpfile=test04.dmp tables=test exclude=STATISTICS
Impdp system/******** directory=expdir dumpfile=test04.dmp sqlfile=test04.sql
发现test04.sql中部包含表分析语句。
结论:
在Oracle 10g 进行数据泵导出时,最好不导出统计信息,到导入后再进行统计信息的收集,省得浪费时间进行无聊的表分析操作,改bug在11g被消除。