暂无图片
暂无图片
2
暂无图片
暂无图片
暂无图片

干货 | 基表SQL执行效率差导致IMPDP导入速度慢分析

东方龙马 2018-12-07
1387

作者 :白玉山

东方龙马 · 上海

我们经常碰到过的生产环境迁移、构建测试环境等场景需要使用impdp导入数据,经常有人遇到impdp导入效率慢,导入挂起,导入索引部分长时间的等待等等问题,对于这些由于各种原因引起的性能问题现象,你是否深入进行分析过,思考过如何确保以后此类导入业务稳定高效?下面我来跟大家讲述一个东方龙马上海团队曾经碰到过的一个案例。



背  景

近日,东方龙马上海团队接到了一个客户的紧急报障电话,在使用impdp进行业务数据迁移时,导入动作迟迟未完成,已经超过了预定的停机时间窗口;我们的工程师立即前往支持,首先了解了客户环境为:


从windows+oracle10g单实例使用expdp导出,在linux+oracle11.2.0.4单实例上使用impdp导入;业务用户数据中有大量表只有很少数据或无数据,这些用户的表对应的索引有25000多个;目前impdp进度处于导入表后的:


Processing object type SCHEMA_EXPORT/TABLE/INDEX/INDEX

对于有经验的DBA来说,看到这一步大多会依据经验初步判断是由于串行建索引或者导入并行度不够,所以比较慢;对于这们本次的问题场景,客户已经提供信息这些索引对应的表数据量非常小,通过在原环境的查看也确认了这一点;目前需要创建的索引约25000个,从dba_objects统计索引总数量的增量来计算,大约5秒左右创建一个,在此次的创建20000多个很小索引的场景,按目前速度索引创建过程需要耗费10几个小时了,大大超过预定停机窗口。


接下来我们按照正常的性能问题排查步骤在目标环境进行排查:



1.找出性能瓶颈点


1.系统资源:CPU/MEMORY/IO,使用正常

2.查看DB中的活动会话等待事件,无明显异常

3.redo log切换正常,业务表空间、临时表空间等使用正常

4.增大了shared pool/streams_pool_size 后,无明显改善

5.查看目标环境数据库AWR报告,也未发现明显异常




2.对IMPDP导入进程进行trace分析

这里首选使用10046 TRACE方式来查看导入进程的具体操作与对应时间。


1.找到IMPDP的进程OSPID:

SQL> select to_char(sysdate,'YYYY-MM-DD HH24:MI:SS') "DATE", s.program, s.sid,    

  2         s.status, s.username, d.job_name, p.spid, s.serial#    

  3    from v$session s, v$process p, dba_datapump_sessions d   

  4   where p.addr=s.paddr and s.saddr=d.saddr;  

DATE       PROGRAM      SID STATUS   USERNAME   JOB_NAME     SPID    SERIAL#

------------------- -------------------------------- ------- -------- ---------- ------------------------------ ------- -------

2018-01-11 11:13:48 oracle@test111 (DW02)            157 ACTIVE   SYSTEM     SYS_IMPORT_FULL_01             9919          1

2018-01-11 11:13:48 oracle@test111 (DW01)            133 ACTIVE   SYSTEM     SYS_IMPORT_FULL_01             9917          5

2018-01-11 11:13:48 oracle@test111 (DW03)            182 ACTIVE   SYSTEM     SYS_IMPORT_FULL_01             9921          1

2018-01-11 11:13:48 oracle@test111 (DW00)             28 ACTIVE   AAA      SYS_IMPORT_FULL_01             9750          3

2018-01-11 11:13:48 oracle@test111 (DM00)              3 ACTIVE   SYSTEM     SYS_IMPORT_FULL_01             9748          1

2018-01-11 11:13:48 udi@test111 (TNS V1-V3)          178 ACTIVE   SYSTEM     SYS_IMPORT_FULL_01             9744          5

6 rows selected.

2.使用oradebug 10046方法跟踪IMPDP进程:

SQL> oradebug setospid 9750

Oracle pid: 31, Unix process pid: 9750, image: oracle@test111 (DW00)

SQL> oradebug event 10046 trace name context forever,level 12;

Statement processed.

SQL>

…………等一段时间

SQL> oradebug event 10046 trace name context off;

Statement processed.

SQL> oradebug tracefile_name

/u01/app/oracle/diag/rdbms/AAORA/AAORA/trace/AAORA_dw00_9750.trc

3.tkprof格式化并分析trace

$ tkprof u01/app/oracle/diag/rdbms/AAORA/AAORA/trace/AAORA_dw00_9750.trc

output = dm2.log

从格式化的trace最后查看,总的执行信息:

OVERALL TOTALS FOR ALL RECURSIVE STATEMENTS

call     count       cpu    elapsed       disk      query    current        rows

------- ------  -------- ---------- ---------- ---------- ----------  ----------

Parse    3034




3.收集数据字典基表统计信息

从10046的TRACE中分析可以发现有两个涉及基表的SQL执行效率不太好,这个时候首选方案是收集系统及数据字典基表统计信息,这里我使用如下过程将相关的统计信息一并收集。


GATHER_DATABASE_STATS Procedures

GATHER_DICTIONARY_STATS Procedure

GATHER_FIXED_OBJECTS_STATS Procedure

GATHER_SCHEMA_STATS Procedures



收集后查看sys.kupc$que_int.receive(:2),收集数据字典信息后恢复正常。但是另一条SQL b7qwhm1b31mv2的执行情况仍未改善,执行计划:


SQL> select SQL_ID,EXECUTIONS,CHILD_NUMBER,HASH_VALUE,ELAPSED_TIME/EXECUTIONS from v$sql where sql_id='b7qwhm1b31mv2';

SQL_ID        EXECUTIONS CHILD_NUMBER HASH_VALUE ELAPSED_TIME/EXECUTIONS

------------- ---------- ------------ ---------- -----------------------

b7qwhm1b31mv2        716            0 1446039394              2452111.12

b7qwhm1b31mv2        487            1 1446039394              3340427.51




4.固定定执行计划

在收集系统及数据字典基表统计信息后有一个SQL执行计划效率仍较低,在此情况下也可以考虑使用人为加hint、本库查看更大范围的AWR数据中是否有此SQL正确 执行计划或者从其它同版本的数据库环境中查看此SQLID的执行计划等方式,得到一个效率高的执行计划,并在目标环境进行固定执行计划的方式来使SQL执行计划效率提升。


关于跨数据库绑定执行计划:

跨数据库的绑定、替换执行计划有多种方式,一般可以使用官方SQLT系列脚本中的coe*系列来简化操作,如不同数据库中的SQLID文本完全一致,在核对相关OPTIMIZER参数后也可以直接使用coe_xfr_sql_profile脚本在测试环境得到正确的绑定执行计划用的sql文件,传输到目标环境运行即可绑定;另外的coe_load_sql_profile脚本  coe _ load _ sql _ baseline 脚本均可以实现不同数据库中执行计划的绑定替换并能够支持做一定的SQL文本修改等操作。


本次我们即使用在同版本的测试库中查看同样SQL的执行计划效率较高,使用其执行计划在目标环境对异常SQL进行执行计划的固定。固定执行计划后此SQL的执行效率:


SQL>select SQL_ID,EXECUTIONS,CHILD_NUMBER,PLAN_HASH_VALUE,SQL_PROFILE,ELAPSED_TIME/EXECUTIONS/1000 "microseconds/1000" from v$sql where sql_id='b7qwhm1b31mv2';

SQL_ID        EXECUTIONS CHILD_NUMBER PLAN_HASH_VALUE SQL_PROFILE                    microseconds/1000

------------- ---------- ------------ --------------- ------------------------------ -----------------

b7qwhm1b31mv2       4955            0      3049612612 coe_b7qwhm1b31mv2_3049612612          1.42824622

AWRSQL的报告查看:




5.问题SQL处理前后的索引创建效率对比

通过前面的处理,查看索引创建速度已经有大幅提高:

① 处理前:37分钟,创建336个,平均一分钟9个

② 处理后:14分钟,创建3022个,平均一分钟215个


处理前:

SQL> select count(*),to_char(sysdate,'yyyymmdd hh24:mi:ss') from dba_objects where object_type='INDEX' and owner in ('AAA','bbb','ccc');

COUNT(*) TO_CHAR(SYSDATE,'

-------- -----------------

19218 20180111 11:35:44

SQL> select count(*),to_char(sysdate,'yyyymmdd hh24:mi:ss') from dba_objects where object_type='INDEX' and owner in ('AAA','bbb','ccc');

  COUNT(*) TO_CHAR(SYSDATE,'

---------- -----------------

19554 20180111 12:12:38


处理后:

SQL> select count(*),to_char(sysdate,'yyyymmdd hh24:mi:ss') from dba_objects where object_type='INDEX' and owner in ('AAA','bbb','ccc');

COUNT(*) TO_CHAR(SYSDATE,'

---------- -----------------

20107 20180111 12:40:15

---

SQL>select count(*),to_char(sysdate,'yyyymmdd hh24:mi:ss') from dba_objects where object_type='INDEX' and owner in ('AAA','bbb','ccc');

COUNT(*) TO_CHAR(SYSDATE,'

---------- -----------------

23129 20180111 12:54:10:





|  北京    |    上海    |   广州    |   成都    |


4008-906-960


文章转载自东方龙马,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论