SQL*Loader导入百万级别数据

生成百万级的数据文件

连接到本地数据库(自己安装的):

找一个合适大小的表:

然后找一个有20行记录的表,对其进行笛卡尔运算,即可生成130万条记录了.

为了更好地体现通用性,我们在输出时对created日期做一下格式转换:

示例代码保存为SQL文件:getobject.sql

示例代码保存为:SQL文件:call.sql

然后在SQL*Plus命令行环境中,执行下列命令即可:

SQL> @[当前路径]call.sql

然后就耐心等待把,132万的记录量,输出也是需要一定时间的.

查看:

初始化环境

创建表:

创建Index.

执行导入

创建控制文件如下:

控制文件保存为:ldr_object.ctl

这里注意,对于CREATED列,我们指定了日期格式,并进行了转换,这个格式一定要与数据文件中日期格式相符,不然日期格式转换时会报错并导致数据加载失败.

按照默认参数执行SQLLDR,看看需要多长时间,同时指定ERRORS参数值为10,明确指定出现10次错误即中止加载:

5.4.4 能不能再快一点呢

SQLLDR常规路径导入时默认一次加载64行,现在要加载的总行数已经达到百万级,十位数显然太小,我们首先尝试修改该值,先直接在后面加个0好了,看看能对效率起到多大的提升:

执行如下命令:sqlldr SCOTT/TIGER CONTROL=ldr_object.ctl ERRORS=10 ROWS=640

日志节选信息:

注意节选信息的第一行,该信息是提示由于640行所占用的空间已经超过了参数BINDSIZE的默认值,因此自动修改到最大可承受的84行,这说明BINDSIZE参数默认值偏小.速度只比刚才小了2秒(变化几乎可以忽略)

再进一步调整BINDSIZE参数值,默认为256k,我们将其修改为10M(1024kb * 1024 * 10 = 10485760),同时将一次加载的行数提高到5000.

时间变得更长,正在研究:

大约时间是:13:48

Oracle LOGO
image-1838

能不能再快一点呢

所有参数默认,只打开直接路径加载:

靠,这个速度才是王道啊!

有没有可能更快呢

这究竟是希望还是欲望,已经说不清楚了,反正没个尽头。

直接导入路径导入可用的参数也有不少,不过我们这里总数据量不大,因此实际能够起到效率提升的不多,我准备主要从以下两个参数入手:

  1. STREAMSIZE : 直接路径加载默认读取全部记录,因此不需要设置ROWS参数,读取到的数据处理后存入流缓存区,即STREAMSIZE参数,该参数默认值为256kb,这里加大到10MB.
  2. DATE_CACHE : 该参数指定一个转换后日期格式的缓存区,以条为单位,默认值1000条,即保存1000条转换后的日期格式,由于我们要导入的数据中有日期列,因此加载该参数值到5000,以降低日期转换带来的开销.

修改参数后执行命令最终形式如下所示:

可能已经达到性能瓶颈:

SQL*Loader加载综述

事实上想在Oracle存储过程中调用SQLLDR非常麻烦,因为SQLLDR是一个执行程序而不是一个接口,在9i之前版本要在存储过程中实现类似功能也很复杂,虽然可以通过UTL_FILE之类的包间接实现,但需要编写大量脚本,考虑字符截取,过滤,判断等诸多事宜。

一个不慎就可能造成执行报错,或者更不慎,执行到一般的时候报错(可能比没执行还要麻烦),幸运的是,9i及之后的版本,Oracle提供了一个新的功能—外部表(External Tables),顾名思义就是数据存储在数据库之外的表,这是一个号称”SQL*Loader替代者”的新特性.

2013/06/05 15:25:57

–EOF–

发表评论

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据