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

news2025/2/25 9:00:14

直接路径插入(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));
declare
  type 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;
begin
  for j in 1..iterations loop
    pids(j) := j;
    pnames(j) := 'No.' || to_char(j);
  end loop;

  moment1 := dbms_utility.get_time;

  forall x in 1..iterations
    insert into t1(id, name) values(pids(x), pnames(x));  
  commit;

  moment2 := dbms_utility.get_time;

  forall x in 1..iterations
    insert /*+ 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.coloradmin.cn/o/1477719.html

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

相关文章

什么是VR紧急情况模拟|消防应急虚拟展馆|VR游戏体验馆加盟

VR紧急情况模拟是利用虚拟现实(Virtual Reality,简称VR)技术来模拟各种紧急情况和应急场景的训练和演练。通过VR技术,用户可以身临其境地体验各种紧急情况,如火灾、地震、交通事故等,以及应对这些紧急情况的…

1.1 创建第一个vue项目

cmd命令窗口运行 vue init webpack hellovue 注意,hellovue是项目名称,项目名称不能保存大写字母否者会报错 Sorry, name can no longer contain capital letters. 运行设个命令的时候可能会报错,根据提示先运行 npm i -g vue/cli-init …

使用Axure RP并配置IIS服务结合内网穿透实现公网访问本地HTML原型页面

文章目录 前言1.在AxureRP中生成HTML文件2.配置IIS服务3.添加防火墙安全策略4.使用cpolar内网穿透实现公网访问4.1 登录cpolar web ui管理界面4.2 启动website隧道4.3 获取公网URL地址4.4. 公网远程访问内网web站点4.5 配置固定二级子域名公网访问内网web站点4.5.1创建一条固定…

ardupilot 及PX4姿态误差计算算法对比分析

目录 文章目录 目录摘要1.APM姿态误差计算算法2.PX4姿态误差计算算法3.结论摘要 本节主要记录ardupilot 及PX4姿态误差计算算法差异对比过程,欢迎批评指正。 备注: 1.创作不易,有问题急时反馈 2.需要理解四元物理含义、叉乘及点乘含义、方向余弦矩阵含义、四元数乘法物理含…

32单片机基础:EXTI外部中断

本节是STM32的外部中断系统和外部中断。 中断系统是管理和执行中断的逻辑结构,外部中断是总多能产生中断的外设之一, 所以本节借助外部中断学习一下中断系统。 下图灰色的,是内核的中断,比如第一个,当产生复位事件时…

枚举(蓝桥练习)

目录 一、枚举算法介绍 二、解空间的类型 三、循环枚举解空间 四、例题 (一、反倍数) (二、特别数的和) (三、找到最多的数) (四、小蓝的漆房) (五、小蓝和小桥的…

Visual Studio:指针和固定大小缓冲区只能在不安全的上下文中使用、 设置允许使用不安全代码(unsafe)

问题描述: 指针和固定大小缓冲区只能在不安全的上下文中使用 解决方案: 1、解决方案资源管理器-》选择项目-》右键-》属性 2、在生成窗口中,勾选“允许不安全代码” 3、再次“生成解决方案”即可

THINKPHP 跨域报错解决方案

报错:has been blocked by CORS policy: Response to preflight request doesnt pass access control check: No Access-Control-Allow-Origin header is present on the requested resource. 环境:thinkphp6 nginx 今天和VUE配合调用接口的时候发现跨…

【MySQL】MySQL数据管理——DDL数据操作语言(数据表)

目录 创建数据表语法列类型字段属性SQL示例创建学生表 查看表和查看表的定义表类型设置表的类型 面试题:MyISAM和InnoDB的区别设置表的字符集删除表语法示例 修改表修改表名语法示例 添加字段语法示例 修改字段语法示例 删除字段语法示例 数据完整性实体完整性域完整…

Window系统部署Z-blog并结合内网穿透实现远程访问本地博客站点

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

基于光流法以及背景减除法的降雪检测项目知识点总结

项目总结目录 一、算法部分1.光流法部分知识点2.python代码与大华摄像头之间的实时调用3.两个方法的代码 一、算法部分 1.光流法部分知识点 像素坐标系与直角坐标系之间的转换,之后计算角度。 其中光流法通过判断运动目标的角度来识别是否为降雪,通过…

VS2019 - 未启用调试

在昨天的工作中,遇到了下面的报错,提示的我感觉很莫名其妙,最后找到了解法,记录一下。 弹窗提示 原因 修改了Web.config文件,并且没有保存,也没关闭已经打开的Web.config文件。 解决方案 保存并没关闭已…

部分卷积与FasterNet模型详解

简介 论文原址:2023CVPR:https://arxiv.org/pdf/2303.03667.pdf 代码仓库:GitHub - JierunChen/FasterNet: [CVPR 2023] Code for PConv and FasterNet 为了设计快速神经网络,很多工作都集中于减少浮点运算(FLOPs&a…

(libusb) usb口自动刷新

文章目录 libusb自动刷新程序Code目录结构Code项目文件usb包code包 效果描述重置reset热拔插使用 END libusb 在操作USB相关内容时,有一个比较著名的库就是libusb。 官方网址:libusb 下载: 下载源码官方编好的库github:Release…

Mysql REGEXP正则运算符

# 邮箱h开头 mysql> select email form xxx where email REGEXP ^h;

就业班 2401--2.28 Linux Day7--存储管理1

一 .存储管理 主要知识点: 基本分区、逻辑卷LVM、EXT3/4/XFS文件系统、RAID 初识硬盘 机械 HDD 固态 SSD SSD的优势 SSD采用电子存储介质进行数据存储和读取的一种技术,拥有极高的存储性能,被认为是存储技术发展的未来新星。 与传统硬盘相比&#…

单点登录的三种方式

前言 在B/S系统中,登录功能通常都是基于Cookie 来实现的。当用户登录成功后,一般会将登录状态记录到Session中,或者是给用户签发一个 Token,无论哪一种方式,都需要在客户端保存一些信息(Session ID或Token)&#xff0…

服务器数据恢复-异常断电导致服务器硬盘离线的数据恢复案例

服务器数据恢复环境: dell某型号服务器中有一组通过raid卡组建的raid10,该raid阵列中一共有4块磁盘。上层部署XenServer虚拟化平台,作为网站服务器使用。 服务器故障: 服务器异常断电导致服务器上的一台虚拟机不可用。需要恢复这…

优维全面可观测产品能力分解④:故障可观测

《优维全面可观测产品能力分解》系列文章的第一篇,介绍了「架构可观测」是从系统架构的视角来呈现链路与服务的状态数据;第二篇介绍了「变更可观测」是从变更的角度看系统状态的变化,及与事件的关联关系;第三篇介绍了「应用服务可…

配置资源管理Secret

目录 一、什么是Secret? 二、secret的三种类型 三、pod适用secret的三种方式 四、secret实例 1、创建secret 2、使用Secret方式 一、什么是Secret? Secret 是用来保存密码、token、密钥等敏感数据的 k8s 资源,目的是为了更方便的控制使用数据,并…