您的位置:必发88 > 科技资讯 > Oracle在插入大量数据时速度会越来越慢,请问有

Oracle在插入大量数据时速度会越来越慢,请问有

2019-10-05 15:13

问:Oracle在插入大量数据时速度会越来越慢,请问有什么解决办法?

加快oracle数据库插数据速度方法:

从编程角度考虑:

1 使用绑定变量,达到一次预编译多次执行的效果。如果不使用绑定变量,数据库每次都要对sql进行分析,消耗资源。

2 使用oracle提供的批量接口,这样可以减少网络传输次数,加快效率

3 适当增加commit间隔,commit指令比较消耗数据库资源,尽量多插入一些数据再提交。建议一千条以上。

4 使用hint(如+append),使用insert 语句 nologging选项,减少数据库日志登记。

5 考虑使用多进程插入或者使用并行hint插入

从数据库角度考虑:

1 把表改成nologging模式,这样不用登记回滚日志

2 对表进行分区,让不同分区落在不同硬盘

3 把表的索引删除,插完数据后再恢复

4 增大数据库缓冲区

5 使用ssd存储等高效硬盘作为数据库存储

其他细节:

例如把程序部署到数据库服务器再操作,减少网络消耗

插入数据程序输出日志重定向到硬盘

以我多年实际维护 Oracle 的实际经验,来解答题主的疑问。

我以最常见的插入场景进行举例: 假设要将表 B 中的数据, 复制插入到 A 表中, 2 张表都同在一台Oracle 数据库服务器里,服务器的 CPU 数量为 16 CPU。


一、 使用并行(parallel)技术提升速度

仅针对本题主的疑问,主要是为了实现快速的将数据从 B表插入到A表,以对数据库服务器变动最小的前题出发,我们可以采用并行(parallel)技术,即调用更多的服务器CPU资源,实现将数据快速插入。

将B表的数据,使用并行技术插入到A表,使用并行技术的SQL 语句如下:

SQL>insert /*+ parallel (A 6) */ into A select /*+ parallel (B 6) */ * from B;

命令说明:

select /*+ parallel (B 6)*/ * from B 是调用 6 个 CPU 资源,同时读取源表B数据

insert /*+ parallel (A 6)*/ into A 是调用 6 个 CPU 资源,同时将数据插入A表

2个并行参数,一共调用了12 个 CPU资源,服务器一共有16 CPU,还余 4 CPU资源供系统使用,不会存在 CPU 跑满的问题。


二、 使用直接插入(append)技术进一步提升速度

如果上述的方法还不够快( 方法一 数据库在插入时,会写重做日志 undo log)因此会占用一些Oracle资源,可以结合直接路径插入方式(append),让Oracle不写重做日志(undo log),从而进一步提升插入数据的速度。

将B表的数据,使用并行技术插入到A表,结合直接路径插入的SQL 语句如下:

SQL>insert /*+ append parallel (A 6) */ into A select /*+ parallel (B 6) */ * from B;

命令说明:

append 的作用就是直接路径写入数据到表,而不写重做日志 undo log,从而进一步提升数据的插入速度。


以上就是可以实现数据快速插入的方式,希望能够帮助到题主和阅读此问题的朋友。

不懂Oracle,就算法原理上说,插入跟追加是有区别的。根据你“越来越慢”的描述,应该是用了插入机制,但不影响速度的却是追加。大量数据灌库,优先选择追加,不用管排序,灌入後再建立索引得到逻辑排序。

插入使用物理排序,若使用前插方式,则每插一笔记录要把後面的所有记录往後搬移,腾出一处空行供插入数据,後面的记录少时没什么,但若後面的记录多起来,搬移的速度肯定越来越慢。根据现象描述,这是极可能的情形。我建议你动手测试看看这个数据库的insert实现到底是怎么做的。

若数据库没append指令,看看insert有没有Alfter之类的参数,避免默认before。

多线程在理论上不能解决问题,除非数据库本身是分物理磁盘存放的,若是在同一文件中,始终要按顺序写入库文件,也无法让磁盘并行读写。

另一种解决的算法,当非要物理前插不可的时候,可以一次挪出足够的空间,然后灌入数据。

这些方案取决于数据库如何优化SQL语句的实现,但若程序员自己没有手动编程操纵过数据库管理的经验,根本不知道可能有什么优化方案。SQL是标准语法,但只规定语法的标准形式,具体实现如何是数据库系统由编制者决定,不同的数据库实现同一条SQL语句的方式极可能不同,这与网页浏览器实现HTML标准的情形相似,也与C编译器编译C代码的情形相似。

这种往数据库中添加数据的原理,实际上与C++的vector类型机制相似,永远是末尾追加的效率最高,插入数据是劣质选择。想象一个模型,数据库就如多米诺骨牌,每条记录是一个骨牌,添加记录最快的方法当然在後面加骨牌,不论加多大量的骨牌,速度只与摆放的效率有关,要在中间插功夫就多了,纵然多CPU作业,每个CPU也要等前面的摆好了才能摆下一个,磁盘的写入也是写好一块才能写下一块,除非是不同的物理磁盘,这样能快到哪去,顶多把需要添加的数据更快地读到内存罢了,内存不够更糟糕。大型数据库的管理,不会神化到何等程度,它要提高效率,无非如vector一样事先预留增长空间,添加越多,预留的幅度越大,故这类数据库往往数据量不多但体积庞大。学C、学算法、学数据结构,都是为了明白这些道理,数据库、SQL再高级,也绕不过这些最基本的东西。

不存在这个问题

既然是大量数据插入 它是一个批处理 你怎么知道越来越慢的 要么就直接跑几个小时 怎么就越来越啦?

数据插入 无非是加锁 写日志 写热数据 后来定时回盘

如果比以往慢 一般就是还有其他大事务

本文由必发88发布于科技资讯,转载请注明出处:Oracle在插入大量数据时速度会越来越慢,请问有

关键词: 请问 oracle 插入 速度