Oracle 直接路径插入(Direct-Path Insert)

直接路径插入(Direct Path Insert)是Oracle一种数据加载提速技术,可以在使用insert语句或SQL*Loader工具大批量加载数据时使用。直接路径插入处理策略与普通insert语句完全不同,Oracle会通过牺牲空间,安全性,并发性能来换取加载速度。

一、Direct-path Insert简介

普通insert语句叫做"传统插入"(Conventional Insert),数据在插入过程中会先缓存在buffer cache中,写入磁盘时会检查并重用数据块中的可重用空间,记录redo日志,维护完整性约束等,这些维护操作都是性能开销,而"直接路径插入"会忽略这些维护操作,换取插入性能的提升。

在海量数据加载场景,特别是向新表大批量加载数据时(加载数据存在原始备份、新表没有可重用空间、并发访问很低)。我们的第一需求可能是加载速度。针对此类场景Oracle提供了一种性能更高的数据加载方式:“直接路径插入”(Direct-Path Insert)。

传统插入与直接路径插入主要有以下5点区别:

  • 传统插入会经过buffer cache缓存后再写数据文件,而直接路径插入会直接写数据文件,这也是Direct-Path Insert名称的由来。
  • 传统插入会重用数据块中的空闲空间,即新旧数据混在一起。而Direct-Path Insert会直接在高水位线(High-Water Mark, HWM)之上追加写数据,即只在新的数据块中写数据,旧数据块中即使有空间也不会重用(更多的空间消耗)
  • 传统插入会维护引用完整性约束,Direct-Path Insert不会维护完整性约束(必须删除或禁用引用完整性约束)
  • 传统插入必须生成redo日志,Direct-Path Insert可以选择关闭redo日志(无法进行Media Recovery)
  • 传统插入不会影响表上其他DML操作,而Direct-Path Insert会获取表级的X锁,因此表上的insert, delete, update都会被阻塞(无法并发)

二、Direct-Path Insert应用场景

Direct-Path Insert可以在下列场景中使用:

  • 使用insert into … values … 语句时通过hint指示Oracle使用Direct-Path Insert
  • 使用insert into … as select … 语句时通过hint指示Oracle使用Direct-Path Insert
  • 使用并行执行,Oracle会自动使用Direct-Path Insert
  • 使用SQL*Loader工具向加载数据时指定使用Direct-Path Insert

2.1 insert into … values … 语句使用Direct-Path Insert

少量的insert into … values …语句通常没必要使用直接路径插入。而在PL/SQL程序中,如果需要通过insert into … values … 语句插入大量数据,则可以选择直接路径插入来提升执行速度。通过在insert关键字后附加/*+ append_values */提示来指示Oracle使用直接路径插入。

示例:建立2张同样的表,分别用传统插入和直接路径插入向表中加载1000万的数据,并记录执行时间:

create table t1(id integer, name varchar2(32));
create table t2(id integer, name varchar2(32));
declaretype idtype is table of t1.id%type index by pls_integer;type nametype is table of t1.name%type index by pls_integer;pids idtype;pnames nametype;iterations constant pls_integer := 10000000;moment1 integer;moment2 integer;moment3 integer;
beginfor j in 1..iterations looppids(j) := j;pnames(j) := 'No.' || to_char(j);end loop;moment1 := dbms_utility.get_time;forall x in 1..iterationsinsert into t1(id, name) values(pids(x), pnames(x));  commit;moment2 := dbms_utility.get_time;forall x in 1..iterationsinsert /*+ append_values */ into t2(id, name) values(pids(x), pnames(x)); commit;moment3 := dbms_utility.get_time;dbms_output.put_line('Execution Time Compare (seconds):');dbms_output.put_line('----------------------------------');dbms_output.put_line('Conventional Insert: '|| to_char((moment2 - moment1)/100));dbms_output.put_line('Direct-Path Insert: '|| to_char((moment3 - moment2)/100));
end;
/

在这里插入图片描述

  • 表t1和t2的表结构相同,使用循环向其中插入1000万条数据
  • 第一个循环使用传统插入,耗时7.14秒,第二个循环使用直接路径插入,耗时3.52秒

2.2 insert into … select … 子查询直接路径插入

使用insert into … select … 通过子查询向表中加载数据时,在insert或select关键字后附加/*+ append */提示来使用直接路径插入。

示例:将表t2的数据使用Direct-Path Insert加载到t1中

insert /*+ append */ into t1 select * from t2;
commit; 
insert into t1 select /*+ append */ * from t2;
commit;

在这里插入图片描述
注意:使用直接路径插入的数据,在提交前是不能查询和更新的,必须显式commit之后才可以使用。上面的两个insert语句中间必须有一个commit,否则第二条insert会失败(ORA-12838)

2.3 并行模式下使用Direct-Path Insert

当开启并行模式后,insert语句会自动变为Direct-Path Insert,但也可以选择使用提示/*+ noappend parallel */来禁用Direct-Path Insert。

示例:使用并行模式,首先要在会话级别打开并行DML:

alter session enable parallel dml;

在这里插入图片描述
检查是否满足下面3个条件中的任意一个(满足任意条件即可使用Direct-Path Insert):

  • 表已经打开并行属性
  • insert的时候显式使用parallel提示
  • 将初始化参数parallel_degree_poicy设置为auto

修改表的并行属性和在insert语句中显式使用parallel提示:

alter table t1 parallel;
insert /*+ parallel(t1,4) */ into t1 select * from t2;

在这里插入图片描述
修改parallel_degree_policy参数需要较高的权限:

alter system set parallel_degree_policy=auto;

在这里插入图片描述

2.4 使用SQL*Loader工具时指定Direct-Path Insert

SQL* Loader是Oracle提供的一个数据加载工具,用于将数据从外部文件加载到数据库的表中。在加载数据时,可以采用Direct-Path Insert提升加载速度。由于SQL* Loader的功能非常强大,使用也稍复杂,下面仅使用SQL*Loader的Express模式(不需要控制文件,且有大量默认选项)演示直接路径插入。

SQL* Loader加载数据时,指定direct=true选项可以指示其使用Direct-Path Insert,这里准备了一个简单的数据文件t1.dat,只有3行数据。
在这里插入图片描述
采用SQL* Loader的express模式将数据加载进入表t1,加载时指定direct=ture:

sqlldr hr/hr table=t1 direct=true

在这里插入图片描述

  • SQL*Loader的express模式会自动在当前目录下搜索table_name.dat文件,所以这里不需要指定数据文件
  • 日志的Path used: Direct代表其采用了直接路径插入

三、Direct-Path Insert与重做日志

与传统插入强制生成重做日志不同,Direct-Path Insert可以选择关闭重做日志的生成,减少性能开销(但也意味着无法进行Media Recovery)。

如果关闭了重做日志,Oracle只会生成很少量的无效重做日志,万一数据库崩溃了,这些使用Direct-Path Insert插入的数据块会被标记为损坏(因为没有重做日志无法进行Media Recovery),因此建议使用nologging模式插入数据后进行一次备份。

通过修改表/索引/分区/LOB的logging模式,可以关闭和打开该对象上重做日志的生成:

alter table t1 nologging;
alter table t1 logging;

在这里插入图片描述
注意:如果DBA在数据库或表空间级别设置的了force logging,那么你在表级别是无法关闭重做日志的,即使使用nologging选项也会被忽略。

alter database force logging;
alter database no force logging;

在这里插入图片描述

alter tablespace users force logging; 
alter tablespace users no force logging;

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/709169.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

opengles 绘制图元 ——glDrawArrays() 相关API介绍 (十)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、opengles3.0 绘制图元介绍二、绘图图元 API 介绍1. glDrawArrays()1.1 glDrawArrays()函数原型1.2 GL_TRIANGLES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN 三者的区别1.3 使用GL_TRIANGLES, G…

springboot+maven项目导入本地jar包,以有打包错误问题

1 本地jar包放置路径为: 2添加Modules File->project settings–>Modules–>Dependencies–>–>, 3 添加 Libraies 至此 项目即可成功运行。 mvn 打包错误,需要 运行以下命令 mvn install:install-file -Dfile${project.basedir}/s…

52.2k star! 自己部署gpt4free, 免费使用各种GPT

GPT4Free是一个由开发者Xtekky在GitHub上发布的开源项目,它可以免费地使用GPT-3.5、GPT-4、llama、gemini-pro、bard、claude等多种大模型。截止到当前(2024.1.30)已经有52.2k star,可见其受欢迎程度。 github地址:https://github.com/xtekky…

拜登:“一切非 Rust 项目均为非法”,开发界要大变天?

文章目录 科技巨头应为安全漏洞负起责任使用其他语言的开发者​该何去何从? 白宫国家网络总监办公室(ONCD,以下简称网总办)在本周一发布的报告中说道:“程序员编写代码并非没有后果,他们的⼯作⽅式于国家利…

Leetcode 134. 加油站 java版 如何解决环路加油站算法

# 官网链接:. - 力扣(LeetCode) 1. 问题描述: 在一条环路上有 n 个加油站,其中第 i 个加油站有汽油 gas[i] 升。 你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i1 个加油站需要消耗汽油 cost[i] 升…

C语言之操作符详解

文章目录 一、算术操作符二、移位操作符1、 原码、反码、补码2、左移操作符3、右移操作符 三、位操作符1、按位与【&】2、按位或【|】3、按位异或【^】4、按位取反【~】5、两道面试题6、进制定位将变量a的第n位置为1将变量a的第n位置为0 四、赋值操作符1、复合赋值符 五、单…

Linux系统---nginx(4)负载均衡

目录 1、服务器配置指令 ​编辑 1.1 服务器指令表 1.2 服务器指令参数 2、负载均衡策略指令 2.1 轮询 (1) 加权轮询 (2) 平滑轮询 2.2 URL 哈希(一致性哈希) 2.3 IP哈希策略 2.4 最少连接 Nginx 负载均衡是由代理模块和上…

【STM32】STM32学习笔记-WDG看门狗(46)

00. 目录 文章目录 00. 目录01. WDG简介02. IWDG概述03. IWDG框图04. IWDG键寄存器05. WWDG简介06. WWDG框图07. WWDG工作特性08. IWDG和WWDG对比09. 预留10. 附录 01. WDG简介 WDG(Watchdog)看门狗 看门狗可以监控程序的运行状态,当程序因为…

嵌入式烧录报错:板端IP与PC的IP相同

报错: 配置 实际上我配置并没有错。 服务器IP(就是本机)、板端IP、网关。此处网关必须与板子IP配套(可以不存在)。 解决 我网卡配置了多个IP。一番删除添加还是报错。 于是点击服务器IP,换成别的&#x…

鸿蒙OS应用编程实战:构建未来应用的基石

💂 个人网站:【 海拥】【神级代码资源网站】【办公神器】🤟 基于Web端打造的:👉轻量化工具创作平台💅 想寻找共同学习交流的小伙伴,请点击【全栈技术交流群】 引言 鸿蒙OS(HarmonyOS&#xff0…

CentOS7如何使用Docker部署Wiki.Js知识库并实现公网远程访问?

文章目录 1. 安装Docker2. 获取Wiki.js镜像3. 本地服务器打开Wiki.js并添加知识库内容4. 实现公网访问Wiki.js5. 固定Wiki.js公网地址 不管是在企业中还是在自己的个人知识整理上,我们都需要通过某种方式来有条理的组织相应的知识架构,那么一个好的知识整…

网络工程师笔记4

协议 端口号 FTP 21、20 HTTP 80 Telnet 23 SMTP 25 TCP头部 TCP三次握手 TCP重传机制:超…

【ArcPy】验证输入字段是否有效

实例展示 代码 def __init__(self):self.parameters arcpy.GetParameterInfo() def updateMessages(self):if(self.parameters[0].value and self.parameters[1].value):shpPathself.parameters[0].valueAsTextfileNameself.parameters[1].valueAsTextworkspacearcpy.Describe…

仿牛客网项目---用户注册登录功能的实现

从今天开始我们来写一个新项目,这个项目是一个完整的校园论坛的项目。主要功能模块:用户登录注册,帖子发布和热帖排行,点赞关注,发送私信,消息通知,社区搜索等。这篇文章我们先试着写一下用户的…

如何在群晖NAS中开启FTP服务并实现公网环境访问内网服务

文章目录 1. 群晖安装Cpolar2. 创建FTP公网地址3. 开启群晖FTP服务4. 群晖FTP远程连接5. 固定FTP公网地址6. 固定FTP地址连接 本文主要介绍如何在群晖NAS中开启FTP服务并结合cpolar内网穿透工具,实现使用固定公网地址远程访问群晖FTP服务实现文件上传下载。 Cpolar内…

SHARE 100M PRO:航测新高度,精准捕捉每一帧

SHARE 100M PRO:单镜头航测相机的革新,巡检效率与精度的新标杆 在航测和巡检领域,精确的数据采集对于确保项目成功至关重要。SHARE 100M PRO,作为一款单镜头航测相机,以其卓越的性能和创新技术,正在重新定…

【活动】前端世界的“祖传代码”探秘:从古老魔法到现代重构

作为一名前端工程师,我时常在项目中邂逅那些被岁月打磨过的“祖传代码”。它们就像古老的魔法书页,用HTML标签堆砌起的城堡、CSS样式表中的炼金术,以及JavaScript早期版本中舞动的符咒。这些代码承载着先驱们的探索精神和独特智慧&#xff0c…

智慧应急:构建全方位、立体化的安全保障网络

一、引言 在信息化、智能化快速发展的今天,传统的应急管理模式已难以满足现代社会对安全保障的需求。智慧应急作为一种全新的安全管理模式,旨在通过集成物联网、大数据、云计算、人工智能等先进技术,实现对应急事件的快速响应、精准决策和高…

Linux读写锁相关函数及操作

读写锁: 概念:读写锁也叫共享-独占锁。当读写锁以读模式锁住时,它是以共享模式锁住的;当它以写模式锁住时,它是以独占模式锁住的。(写独占,读共享)。 读写锁使用场所: …

AI未来10年展望

人工智能(AI)在过去十年中迅速发展,其未来有望取得更加引人注目的发展。 在本文中,我们将探讨人工智能的未来 10 年以及我们对未来十年的期望。 我们将解决一些关键问题,以全面概述人工智能的未来。 1、10年后AI会发展…