DM8数据库统计信息的导入导出
关于统计信息的重要性,我觉着无需多言,本文仅讨论在一些迁移场景中对统计信息的迁移。因一些表的统计信息在重新收集统计信息时可能因环境不同或DBA对业务的了解不够造成统计信息收集发生偏差,最终造成SQL的执行计划是错误的。
这里仅讨论利用dexp和dimp对表数据的迁移。因dexp和dimp默认不会对源库中表的统计信息进行迁移。所以我们利用将目标表的统计信息导入到中间表,再利用dimp将此存储统计信息的中间表导入到目标库中的原理进行统计信息迁移。
预备环境student表:
SQL> CREATE TABLE STUDENT( 2 NAME VARCHAR(20), 3 AGE INT PRIMARY KEY, 4 SEX VARCHAR(10) CHECK (SEX IN ('MAIL','FEMAIL')), GRADE INT CHECK (GRADE IN (7,8,9))) 5 PARTITION BY LIST(GRADE) 6 SUBPARTITION BY LIST(SEX) SUBPARTITION TEMPLATE 7 ( 8 SUBPARTITION Q1 VALUES('MAIL'), 9 SUBPARTITION Q2 VALUES('FEMAIL') 10 ), 11 SUBPARTITION BY RANGE(AGE) SUBPARTITION TEMPLATE 12 ( 13 SUBPARTITION R1 VALUES LESS THAN (12), 14 SUBPARTITION R2 VALUES LESS THAN (15), 15 SUBPARTITION R3 VALUES LESS THAN (MAXVALUE) 16 ) 17 ( 18 PARTITION P1 VALUES (7), 19 PARTITION P2 VALUES (8), 20 PARTITION P3 VALUES (9) 21 ); 警告: 列表分区未包含DEFAULT,可能无法定位到分区 操作已执行 已用时间: 47.376(毫秒). 执行号:512. SQL> insert into student VALUES ('a',10,'MAIL',7); 影响行数 1 已用时间: 1.818(毫秒). 执行号:513. SQL> SQL> insert into student VALUES ('b',11,'MAIL',8); 影响行数 1 已用时间: 0.834(毫秒). 执行号:514. SQL> SQL> insert into student VALUES ('c',13,'MAIL',9); 影响行数 1 已用时间: 1.272(毫秒). 执行号:515. SQL> SQL> insert into student VALUES ('d',16,'MAIL',7); 影响行数 1 已用时间: 0.840(毫秒). 执行号:516. SQL> SQL> commit; 操作已执行 已用时间: 1.032(毫秒). 执行号:517. |
统计信息的查看
SQL> SELECT SAMPLE_SIZE,LAST_ANALYZED FROM DBA_TABLES WHERE table_name = 'STUDENT'; 行号 SAMPLE_SIZE LAST_ANALYZED ---------- ----------- ------------- 1 NULL NULL SQL> select * from sysobjects where name = 'STUDENT'; --1541 行号 NAME ID SCHID TYPE$ SUBTYPE$ PID VERSION CRTDATE ---------- ------- ----------- ----------- ------ -------- ----------- ----------- -------------------------- INFO1 INFO2 INFO3 INFO4 INFO5 ----------- ----------- -------------------- -------------------- ---------- INFO6 INFO7 INFO8 VALID -------------------------------------------------- -------------------- ---------- ----- 1 STUDENT 1541 150994945 SCHOBJ UTAB -1 0 2023-01-18 14:15:55.427000 2097152 0 4503599627436043 0 NULL 0x000000000000000000000000000000000100000000000000 NULL NULL Y 已用时间: 0.642(毫秒). 执行号:520. SQL> select * from sysstats where id='1541'; 未选定行 已用时间: 0.664(毫秒). 执行号:521. |
统计信息收集(使用了dbms_stats包,参考DM8系统包使用手册)
--收集SYSDBA模式下所有对象的统计信息,包括索引 SQL> DBMS_STATS.GATHER_SCHEMA_STATS('SYSDBA',100,FALSE,'FOR ALL COLUMNS SIZE AUTO'); DMSQL 过程已成功完成
SQL> DBMS_STATS.GATHER_TABLE_STATS ('SYSDBA', 'STUDENT',NULL,100,FALSE,'FOR ALL COLUMNS SIZE AUTO'); DMSQL 过程已成功完成 已用时间: 200.984(毫秒). 执行号:524. |
统计信息备份及导入
SQL> call dbms_stats.CREATE_STAT_TABLE('SYSDBA', 'STUDENT_STAT'); DMSQL 过程已成功完成 已用时间: 8.807(毫秒). 执行号:526. SQL> SELECT * FROM STAT$_STUDENT_STAT; 未选定行 SQL> call dbms_stats.EXPORT_TABLE_STATS('SYSDBA', 'STUDENT', null, 'STUDENT_STAT', '1', TRUE); DMSQL 过程已成功完成 已用时间: 92.940(毫秒). 执行号:528. SQL> SELECT count(*) FROM STAT$_STUDENT_STAT; 行号 COUNT(*) ---------- -------------------- 1 141 已用时间: 0.877(毫秒). 执行号:530. SQL> (结果略) |
使用plsql块进行导出导入(实际环境中通常不是一张表,使用plsql块更加方便,可以批量导出一个模式下的所有表)。记住导出导入前先生成下统计信息中间表。也别忘记这个表的命名规则是:’STAT$_[你创建的中间表名]’,如:STAT$_STUDENT_STAT。
--导出 begin for i in ( select a.owner, a.table_name from all_tables a where a.owner='TEST' ) loop call dbms_stats.export_table_stats(i.owner,i.table_name,null, 'TEST_STAT', '1', TRUE); END LOOP; END; --统计信息存放表的导入导出参考上一步 --导入 begin for i in ( select a.owner, a.table_name from all_tables a where a.owner='TEST' ) loop call dbms_stats.import_table_stats(i.owner,i.table_name,null, 'TEST_STAT', '1', TRUE); END LOOP; END; |
达梦数据库技术社区:https://eco.dameng.com