暂无图片
暂无图片
1
暂无图片
暂无图片
暂无图片

Oracle|Oracle数据库expdp导出分区表异常缓慢问题分析

安呀智数据坊 2025-02-07
45

注: 本文为安丫科技焱焱枫的原创,请尊重知识产权,转发请注明出处,不接受任何抄袭、演绎和未经注明出处的转载。

某客户在使用expdp(Data Pump Export)工具导出某分区表时,耗时远超预期(原预计20分钟,实际耗时超过1小时)。

01

 问题描述  

客户反馈

某客户在使用expdp(Data Pump Export)工具导出某分区表时,耗时远超预期(原预计20分钟,实际耗时超过1小时)。


执行的导出日志如下:

    starting "SYS"."SYS_EXPORT_TABLE_01":'******** AS SYSDBA" PART_TAB001.10g tabTeS=TEST.PART_TAB001
    Estimate in progress using BLocks method...
    Processing object type TABLE_EXPORT/TABLE/TABLE_DATA
    ...等待中....


    02

     故障分析过程  

    注意以下涉及的表名均已脱敏。

    1. 环境信息

    数据库版本:Oracle 11g

    表信息:

    • 表名:TEST.PART_TAB001

    • 分区类型:范围分区(Range Partition)

    • 数据量:约800GB(共200个分区)

    • 硬件配置:储为SAN,CPU 64核,内存512GB


    2. 初步排查

    1)导出状态分析:

    检查expdp导出状态:

      expdp \'\/ as sysdba\' attach=SYS_EXPORT_TABLE_01

      结果显示任务均在正常执行中。


      2)会话监控

      • 当前等待事件显示主要的等待在CPU上


      • 通过v$session和v$sql 进一步跟踪长事务SQL,发现一条查询导出表的SQL

        SELECT NVL((SELECT *+ NESTED_TABLE_GET_REFS */ 1
        FROM "TEST"."PART_TAB001" SUBPARTITION ("SYS_SUBP2107") WHERE ROWNUM = 1), 0) FROM DUAL


        3)OS监控:

        查看操作系统性能指标

        观察到CPU的空闲率所有下降。


        3. 根本原因定位

        1)SQL执行计划分析

        通过DBMS_XPLAN.DISPLAY_CURSOR获取SQL执行计划:

          ******************************************************************************
          SELECT NVL((SELECT *+ NESTED_TABLE_GET_REFS */ 1
          FROM "TEST"."PART_TAB001" SUBPARTITION ("SYS_SUBP2107") WHERE ROWNUM = 1), 0) FROM DUAL


          call count cpu elapsed disk query current rows
          ------- ------ -------- ---------- ---------- ---------- ---------- ----------
          Parse 1 0.00 0.00 0 0 0 0
          Execute 1 0.00 0.00 0 0 0 0
          Fetch 1 5.68 70.26 42616 42673 0 1
          ------- ------ -------- ---------- ---------- ---------- ---------- ----------
          total 3 5.68 70.26 42616 42673 0 1


          Rows Row Source Operation
          ------- ---------------------------------------------------
          1 COUNT STOPKEY (cr=42673 pr=42616 pw=0 time=70266787 us)
          1 INDEX FULL SCAN PART_TAB001_UK (cr=42673 pr=42616 pw=0 time=70266777 us)(object id 80566)
          1 FAST DUAL (cr=0 pr=0 pw=0 time=3 us)
          ********************************************************************************

          问题点:

          索引全扫描:执行计划显示对分区表进行了索引全扫描(INDEX FULL SCAN),返回一条数据。


          2)故障分析:

          在执行分区表导出的任务中,Oracle内部会递归调用查询SQL。这本次案例中,对导出的分区表"TEST"."PART_TAB001"所有分区分进行查询。

          由于该SQL走的索引全扫描,为单块读扫描方式,导致效率低下,需要70秒才能完成,那么对于所有200个子分区,需要200 x 70秒,这意味着近4小时才能完成导出。


          03

           解决方案 

          现已确认由于EXPDP调用的递归SQL导致的问题,优化SQL执行效率即可。

          官方建议最好的选择是升级到数据库的支持版本,并应用最新的可用补丁集,当然也可以通过调整参数或收集统计信息处理。


          1. 优化器参数


          当前优化器相关参数:

            optimizer_index_caching = 80
            optimizer_index_cost_adj = 20

            这些参数迫使优化器选择差的执行计划。


            将以下参数设置默认值:

              SQL> connect  as sysdba
              SQL> alter system set optimizer_index_caching = 0;
              SQL> alter system set optimizer_index_cost_adj = 100;



              2. 更新统计信息:

                EXEC DBMS_STATS.GATHER_TABLE_STATS(
                ownname => 'TEST',
                tabname => 'PART_TAB001',
                estimate_percent => 30,
                method_opt => 'for all columns size repeat',
                degree => 8,
                granularity => 'ALL',
                cascade => TRUE
                );


                04

                 验证结果 

                1. 执行计划验证:

                • 优化后执行计划显示TABLE ACCESS FULL。

                • 全表扫描(TABLE ACCESS FULL)取代索引全扫描。

                  ********************************************************************************
                  SELECT NVL((SELECT /*+ NESTED_TABLE_GET_REFS */ 1
                  FROM "TEST"."PART_TAB001" SUBPARTITION ("SYS_SUBP2107") WHERE ROWNUM = 1), 0) FROM DUAL


                  call count cpu elapsed disk query current rows
                  ------- ------ -------- ---------- ---------- ---------- ---------- ----------
                  Parse 1 0.00 0.00 0 0 0 0
                  Execute 1 0.00 0.00 0 0 0 0
                  Fetch 1 0.00 0.00 6 4 0 1
                  ------- ------ -------- ---------- ---------- ---------- ---------- ----------
                  total 3 0.00 0.00 6 4 0 1


                  Rows Row Source Operation
                  ------- ---------------------------------------------------
                  1 COUNT STOPKEY (cr=4 pr=6 pw=0 time=215 us)
                  1 PARTITION COMBINED ITERATOR PARTITION: KEY KEY (cr=4 pr=6 pw=0 time=209 us)
                  1 TABLE ACCESS FULL PART_TAB001 PARTITION: 279 279 (cr=4 pr=6 pw=0 time=203 us)
                  1 FAST DUAL (cr=0 pr=0 pw=0 time=3 us)
                  ********************************************************************************


                  2.导出时间对比:

                  优化前:4小时

                  优化后:25分钟


                  写在最后


                  通过对问题的深入分析,明确了导致 expdp 导出分区表速度缓慢的主要原因是某个关键SQL语句的执行效率低下。

                  针对这一问题提出了一系列优化措施,包括但不限于优化SQL执行计划、调整 expdp 参数设置以及对数据库补丁进行必要的升级。


                  END

                  关键词回复(可见相应文章):

                  oracle、mysql、pg、postgresql、sql、性能优化、故障处理、数据迁移、备份恢复、版本升级、补丁管理、深度巡检、解决方案、架构设计......

                  小助手

                  有任何问题或疑问,欢迎加V进群探讨哦~

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

                  评论