巧用外部表避免大量的insert

简介: 昨天开发咨询我一个问题,希望我对下面的语句进行调优。 语句类似下面的形式 SELECT  subscriber_no  FROM SUBSCRIBER S WHERE SUBSCRIBER_TYPE = 'RM'              and CO...
昨天开发咨询我一个问题,希望我对下面的语句进行调优。
语句类似下面的形式
SELECT  subscriber_no 
FROM SUBSCRIBER S
WHERE SUBSCRIBER_TYPE = 'RM' 
            and CONV_RUN_NO in (20, 21, 22, 23) 
            and not EXISTS (SELECT s.AGREEMENT_NO 
                      FROM SERVICE_AGREEMENT S, CSM_OFFER C 
                      WHERE s.subscriber_no = S.AGREEMENT_NO 
                                   and SOC = C.SOC_CD 
                                   and SOC_TYPE ='P' 
                       ) 

这个语句的执行计划如下:
Plan hash value: 1111602366
---------------------------------------------------------------------------------------------------------
| Id  | Operation                        | Name                 | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                 |                      |     2 |    22 | 56648   (1)| 00:11:20 |
|*  1 |  FILTER                          |                      |       |       |            |          |
|*  2 |   TABLE ACCESS FULL              | SUBSCRIBER           |     2 |    22 | 56646   (1)| 00:11:20 |
|   3 |   NESTED LOOPS                   |                      |       |       |            |          |
|   4 |    NESTED LOOPS                  |                      |     2 |    44 |     2   (0)| 00:00:01 |
|*  5 |     INDEX RANGE SCAN             | SERVICE_AGREEMENT_PK |     8 |   104 |     1   (0)| 00:00:01 |
|*  6 |     INDEX RANGE SCAN             | CSM_OFFER_1IX        |     1 |       |     1   (0)| 00:00:01 |
|*  7 |    MAT_VIEW ACCESS BY INDEX ROWID| CSM_OFFER            |     1 |     9 |     1   (0)| 00:00:01 |
---------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   1 - filter( NOT EXISTS (SELECT 0 FROM "PRDREFSSCA"."CSM_OFFER"
              "C","PRDAPPO"."SERVICE_AGREEMENT" "S" WHERE "S"."AGREEMENT_NO"=:B1 AND "SOC"="C"."SOC_CD" AND
              "SOC_TYPE"='P'))
   2 - filter(("CONV_RUN_NO"=20 OR "CONV_RUN_NO"=21 OR "CONV_RUN_NO"=22 OR "CONV_RUN_NO"=23) AND
              "SUBSCRIBER_TYPE"='RM')
   5 - access("S"."AGREEMENT_NO"=:B1)
   6 - access("SOC"="C"."SOC_CD")
   7 - filter("SOC_TYPE"='P')

从语句来看是真没有多少什么调优空间了。为了想尽快得到结果,我建议加了一个hint  /*+parallel(4)*/
我一再叮嘱他,这中语句最好在备份库中执行,因为备份中的数据是相对比较新的,他也同意。备份库当时负载很低,执行大概用了6分钟的样子。输出结果大约有70多万。
我以为这件事就这么过去了,结果今天早上他找到我说,希望把这70多万条记录存到一个一个临时用户下,需要关联查找更多的细节。
这种问题让人有些纠结。不过为了问题的解决,也不能完全怪他。
尝试一:
首先的一个思想就是想吐省事,在中午的时候尝试生成这些记录。
create table issue_sub_list nologging as 
SELECT  /*+parallel(4)*/ subscriber_no 
FROM SUBSCRIBER S
WHERE SUBSCRIBER_TYPE = 'RM' 
            and CONV_RUN_NO in (20, 21, 22, 23) 
            and not EXISTS (SELECT s.AGREEMENT_NO 
                      FROM SERVICE_AGREEMENT S, CSM_OFFER C 
                      WHERE s.subscriber_no = S.AGREEMENT_NO 
                                   and SOC = C.SOC_CD 
                                   and SOC_TYPE ='P' 
                       ) 
这条语句结果在生产上执行了将近10分钟还没有完成的意思,我查看执行计划的输出列情况,才全表扫描了30%,所以果断终止了这个操作。
这条路不建议使用,我看还有什么别的路可走。
尝试二:
一来就是对得到的数据进一步转换为insert语句。尝试在windows的ultraEdit下面编辑,因为这些id有差不多11M左右,使用文本编辑器没过一会,就提示缓存溢出,卡在那了。
尝试三:
看来文本编辑器还是很有使用限制的,linux环境下的命令方式要相对好很多。百兆上G的日志都没有问题。
我写了如下的脚本。
while read line
do
sqlplus -s n1/n1@xxx   insert into issue_sublist values( $line);
EOF
done 执行的速度来看,单条语句是没有问题的,但是这条语句执行了10多分钟,还没有完,进步还是让人不够满意。
尝试四:
大家使用外部表来查看数据库的日志信息,这是一种方式,我们也可以应用到这个场景中。来看看外部表的情况。
创建了directory 
create directory EXT_DATAPUMP_DIR as '/oravl01/oracle/ext_datapump/DUMP';
grant read,write on directory EXT_DATAPUMP_DIR to n1;
然后使用语句创建了外部表。
create table issue_sublist_ext(text varchar2(1000)) organization external
(type oracle_loader
 default directory EXT_DATAPUMP_DIR
 location('sub_list.log')
);
Table created.
Elapsed: 00:00:00.01
SQL> select count(*)from issue_sublist_ext;
  COUNT(*)
----------
    769685
Elapsed: 00:00:00.25
SQL> drop table issue_sublist;
Table dropped.
Elapsed: 00:00:00.04
我们来创建一个表存储这些数据。
SQL> create table issue_sublist as select *from issue_sublist_ext;
Table created.
Elapsed: 00:00:00.64
SQL> !exp n1/n1@xxx  file=issue_sublist.dmp tables=issue_sublist buffer=910200
About to export specified tables via Conventional Path ...
. . exporting table                  ISSUE_SUBLIST     769951 rows exported
Export terminated successfully without warnings.

来看看dump的情况,生成的dump文件和文本的大小差不多大小。
TRUABP4 /oravl01/oracle/ext_datapump/DUMP > ll
total 24880
-rw-r--r-- 1 oracle dba 11545275 Mar 11 12:04 sub_list.log
-rw-r--r-- 1 oracle dba      357 Mar 11 12:05 ISSUE_SUBLIST_EXT_8860.log
-rw-r--r-- 1 oracle dba 13869056 Mar 11 12:07 issue_sublist.dmp

这个dump拷贝到生产中,直接imp速度是相当快的,一秒内搞定。
> time imp n1/n1 file=issue_sublist.dmp tables=issue_sublist buffer=910200 fromuser=n1 touser=cust_prsnl
. importing N1's objects into CUST_PRSNL
. . importing table                "ISSUE_SUBLIST"     769951 rows imported
Import terminated successfully without warnings.
real    0m1.277s
user    0m0.133s
sys     0m0.060s
通过这个例子我们可以看到,我们尝试尽可能减少生产的负载,使用外部表间接转换为dump,会减少大量的insert语句执行,而且效率也高。可以作为一种参考。

目录
相关文章
|
网络协议 API 数据安全/隐私保护
|
7天前
|
存储 JavaScript 前端开发
JavaScript基础
本节讲解JavaScript基础核心知识:涵盖值类型与引用类型区别、typeof检测类型及局限性、===与==差异及应用场景、内置函数与对象、原型链五规则、属性查找机制、instanceof原理,以及this指向和箭头函数中this的绑定时机。重点突出类型判断、原型继承与this机制,助力深入理解JS面向对象机制。(238字)
|
6天前
|
云安全 人工智能 安全
阿里云2026云上安全健康体检正式开启
新年启程,来为云上环境做一次“深度体检”
1622 6
|
2天前
|
消息中间件 人工智能 Kubernetes
阿里云云原生应用平台岗位急招,加入我们,打造 AI 最强基础设施
云原生应用平台作为中国最大云计算公司的基石,现全面转向 AI,打造 AI 时代最强基础设施。寻找热爱技术、具备工程极致追求的架构师、极客与算法专家,共同重构计算、定义未来。杭州、北京、深圳、上海热招中,让我们一起在云端,重构 AI 的未来。
|
3天前
|
存储 人工智能 自然语言处理
OpenSpec技术规范+实例应用
OpenSpec 是面向 AI 智能体的轻量级规范驱动开发框架,通过“提案-审查-实施-归档”工作流,解决 AI 编程中的需求偏移与不可预测性问题。它以机器可读的规范为“单一真相源”,将模糊提示转化为可落地的工程实践,助力开发者高效构建稳定、可审计的生产级系统,实现从“凭感觉聊天”到“按规范开发”的跃迁。
590 11
|
8天前
|
安全 数据可视化 网络安全
安全无小事|阿里云先知众测,为企业筑牢防线
专为企业打造的漏洞信息收集平台
1335 2
|
7天前
|
缓存 算法 关系型数据库
深入浅出分布式 ID 生成方案:从原理到业界主流实现
本文深入探讨分布式ID的生成原理与主流解决方案,解析百度UidGenerator、滴滴TinyID及美团Leaf的核心设计,涵盖Snowflake算法、号段模式与双Buffer优化,助你掌握高并发下全局唯一ID的实现精髓。
368 160
|
7天前
|
人工智能 自然语言处理 API
n8n:流程自动化、智能化利器
流程自动化助你在重复的业务流程中节省时间,可通过自然语言直接创建工作流啦。
455 6
n8n:流程自动化、智能化利器
|
9天前
|
人工智能 API 开发工具
Skills比MCP更重要?更省钱的多!Python大佬这观点老金测了一周终于懂了
加我进AI学习群,公众号右下角“联系方式”。文末有老金开源知识库·全免费。本文详解Claude Skills为何比MCP更轻量高效:极简配置、按需加载、省90% token,适合多数场景。MCP仍适用于复杂集成,但日常任务首选Skills。推荐先用SKILL.md解决,再考虑协议。附实测对比与配置建议,助你提升效率,节省精力。关注老金,一起玩转AI工具。
|
16天前
|
机器学习/深度学习 安全 API
MAI-UI 开源:通用 GUI 智能体基座登顶 SOTA!
MAI-UI是通义实验室推出的全尺寸GUI智能体基座模型,原生集成用户交互、MCP工具调用与端云协同能力。支持跨App操作、模糊语义理解与主动提问澄清,通过大规模在线强化学习实现复杂任务自动化,在出行、办公等高频场景中表现卓越,已登顶ScreenSpot-Pro、MobileWorld等多项SOTA评测。
1634 7