1.说明

Oracle数据库导入csv文件,
当csv文件较小时,
可以使用数据库管理工具,
比如DBevaer导入到数据库,
当csv文件很大时,
可以使用Oracle提供的sqlldr命令行工具,
能够快速导入大量数据。
在数据库之间进行数据迁移时,
特别是不同类型的数据库,
使用csv文件是一种很好的选择。

2.sqlldr用法

下面介绍sqlldr用法,
有一个USER_INFO.csv文件,
需要导入到数据库中USER_INFO表,
而且有1.5亿条数据,
要求导入耗时尽量小。
这里先介绍基本的导入方式,
然后介绍direct导入方式,
最后介绍parallel导入方式。

3.获取csv文件

USER_INFO.csv文件内容如下,
这里仅选取了三条测试数据:

MSISDN,PROVINCE_CODE,CREATE_TIME
8617512570551,30,2019-10-31 17:16:09
8613063310680,33,2019-10-31 17:16:12
8613295281345,80,2019-10-31 17:16:14

4.创建USER_INFO表

CREATE TABLE "USER_INFO" (
"MSISDN" VARCHAR2(16),
"PROVINCE_CODE" VARCHAR2(4),
"CREATE_TIME"   DATE,
CONSTRAINT "PK_USER_INFO_MSISDN" PRIMARY KEY ("MSISDN")
) TABLESPACE "USERS";COMMENT ON COLUMN "USER_INFO"."MSISDN" IS '用户手机号';
COMMENT ON COLUMN "USER_INFO"."PROVINCE_CODE" IS '省份编码';
COMMENT ON COLUMN "USER_INFO"."CREATE_TIME" IS '用户创建时间';

注意表中字段要和csv文件对应。

5.创建ctl文件

创建名为loaddata_USER_INFO.ctl的控制文件:

options(skip=1,BINDSIZE=20971520, ROWS=10000, READSIZE=20971520, ERRORS=999999999)
load data
infile '/home/oracle/USER_INFO.csv'
insert into table "USER_INFO"
fields terminated by ','
Optionally enclosed by '\''
(MSISDN,PROVINCE_CODE,CREATE_TIME "to_date(:CREATE_TIME, 'yyyy-mm-dd hh24:mi:ss')")

第1行是导入参数配置,
已经是支持大量数据导入的参数方案。

第3行infile指定导入的文件是USER_INFO.csv;

第4行into table前面的insert表示导入方式:

  1. insert :默认方式,在导入记录前要求表为空;
  2. append :在表中追加新导入的记录;
  3. replace :删除旧记录(等价delete from table语句),替换成新导入的记录;
  4. truncate:删除旧记录(等价truncate table语句),替换成新导入的记录;
    into table后面指定导入数据库表USER_INFO,
    且表名必须大写;

第5行指定每一行的字段是以逗号(,)分隔;

第6行指定字段是用两个分号(')包围起来的,可选的;

最后一行对应导入的字段,
注意如果导入的是时间字段,
需要指明时间转换的格式。

6.使用sqlldr导入

指定需要导入的数据库,
以及使用的control文件:

sqlldr userid=yuwen/ai123456@10.21.13.14:1521/orcl control=loaddata_USER_INFO.ctl

导入成功输出日志如下:

SQL*Loader: Release 12.1.0.2.0 - Production on Thu Oct 31 17:37:49 2019Copyright (c) 1982, 2014, Oracle and/or its affiliates.  All rights reserved.Path used:      Conventional
Commit point reached - logical record count 3Table "USER_INFO":3 Rows successfully loaded.Check the log file:loaddata_USER_INFO.log
for more information about the load.

看到3条数据成功导入USER_INFO,
同时会生成loaddata_USER_INFO.log日志,
通过该日志可以查看更详细的导入信息,
如果导入时发生错误,
可以查看到详细的错误信息,
而且还会生成USER_INFO.bad文件,
bad文件原样输出了导入失败的数据。
默认情况下ERRORS达到50个就会停止导入,
如果需要忽略错误继续导入,
可以配置ERRORS最大值为999999999。

7.direct直接路径方式

sqlldr支持direct参数,
使用直接路径方式导效率非常高,
direct参数默认为FALSE,
上面第6步使用的就是默认常规路径方式,
下面使用直接路径方式,
进一步加快数据导入速度。
但是使用直接路径方式会导致表的唯一索引(或主键)失效,
可以在导入前先删除表的唯一索引,
然后在导入完成后重建索引即可,
如果有重复的数据,
需要先去重才能重建索引成功,
经过测试即使需要重建索引,
使用直接路径方式还是比常规路径方式快。

8.创建ctl文件(直接路径方式)

创建名为loaddata_USER_INFO_direct.ctl的控制文件:

options(skip=1,COLUMNARRAYROWS=20971520, ROWS=10000, READSIZE=20971520, ERRORS=999999999)
load data
infile '/home/oracle/USER_INFO.csv'
insert into table "USER_INFO"
fields terminated by ','
Optionally enclosed by '\''
(MSISDN,PROVINCE_CODE,CREATE_TIME "to_date(:CREATE_TIME, 'yyyy-mm-dd hh24:mi:ss')")

这个文件和第5步中的区别在于,
options中的BINDSIZE换成了COLUMNARRAYROWS,
因为BINDSIZE是常规路径绑定数组的大小,
而COLUMNARRAYROWS是直接路径列数组的行数。

9.删除主键

导入前需要先删除USER_INFO表的主键:

ALTER TABLE USER_INFO DROP CONSTRAINT PK_USER_INFO_MSISDN;

10.使用sqlldr导入(直接路径方式)

基本与第6步的命令相同,增加direct=true:

sqlldr userid=yuwen/ai123456@10.21.13.14:1521/orcl control=loaddata_USER_INFO_direct.ctl direct=true

数据成功导入日志如下:

SQL*Loader: Release 12.1.0.2.0 - Production on Fri Nov 1 10:48:10 2019Copyright (c) 1982, 2014, Oracle and/or its affiliates.  All rights reserved.Path used:      DirectLoad completed - logical record count 3.Table "USER_INFO":3 Rows successfully loaded.Check the log file:loaddata_USER_INFO_direct.log
for more information about the load.

11.重建主键

ALTER TABLE USER_INFO ADD CONSTRAINT PK_USER_INFO_MSISDN PRIMARY KEY(MSISDN);

至此使用直接路径方式导入数据成功,
经过测试1.5亿条不重复数据direct方式导入,
花费4分02秒,
然后重建主键花费19分14秒,
总耗时23分16秒。
然而使用常规路径方式导入需要48个小时,
导入效率得到了极大的提升。

12.parallel并行导入

前面使用的是串行方式导入数据,
通过设置parallel为true可以并行导入,
在多核服务器上面能进一步提升导入效率。
需要注意并行方式仅仅在直接路径方式时有效。

13.创建ctl文件(并行方式)

创建名为loaddata_USER_INFO_direct_parallel.ctl的控制文件:

options(skip=1,COLUMNARRAYROWS=20971520, ROWS=10000, READSIZE=20971520, ERRORS=999999999)
load data
infile '/home/oracle/USER_INFO.csv'
append into table "USER_INFO"
fields terminated by ','
Optionally enclosed by '\''
(MSISDN,PROVINCE_CODE,CREATE_TIME "to_date(:CREATE_TIME, 'yyyy-mm-dd hh24:mi:ss')")

这个文件和第8步中的区别在于,
并行方式只支持append导入,
而且要注意USER_INFO表不能有索引,
如果有需要先删除。

14.使用sqlldr导入(并行方式)

基本与第10步的命令相同,增加parallel=true:

sqlldr userid=yuwen/ai123456@10.21.13.14:1521/orcl control=loaddata_USER_INFO_direct_parallel.ctl direct=true parallel=true

数据成功导入日志如下:

SQL*Loader: Release 12.1.0.2.0 - Production on Fri Nov 1 11:08:51 2019Copyright (c) 1982, 2014, Oracle and/or its affiliates.  All rights reserved.Path used:      Direct
SQL*Loader-281: Warning: ROWS parameter ignored in parallel mode.Load completed - logical record count 3.Table "USER_INFO":3 Rows successfully loaded.Check the log file:loaddata_USER_INFO_direct_parallel.log
for more information about the load.

15.sqlldr命令说明

15.1.用法

SQLLDR keyword=value [,keyword=value,...]

15.2.参数说明

参数 说明
userid ORACLE 用户名/口令
control 控制文件名
log 日志文件名
bad 错误文件名
data 数据文件名
discard 废弃文件名
discardmax 允许废弃的文件的数目 (全部默认)
skip 要跳过的逻辑记录的数目 (默认 0)
load 要加载的逻辑记录的数目 (全部默认)
errors 允许的错误的数目 (默认 50)
rows 常规路径绑定数组中或直接路径保存数据间的行数,默认: 常规路径 64, 所有直接路径)
bindsize 常规路径绑定数组的大小 (以字节计) (默认 256000)
silent 运行过程中隐藏消息 (标题,反馈,错误,废弃,分区)
direct 使用直接路径 (默认 FALSE)
parfile 参数文件: 包含参数说明的文件的名称
parallel 执行并行加载 (默认 FALSE)
file 要从以下对象中分配区的文件
skip_unusable_indexes 不允许/允许使用无用的索引或索引分区 (默认 FALSE)
skip_index_maintenance 没有维护索引, 将受到影响的索引标记为无用 (默认 FALSE)
commit_discontinued 提交加载中断时已加载的行 (默认 FALSE)
readsize 读取缓冲区的大小 (默认 1048576)
external_table 使用外部表进行加载; NOT_USED, GENERATE_ONLY, EXECUTE (默认 NOT_USED)
columnarrayrows 直接路径列数组的行数 (默认 5000)
streamsize 直接路径流缓冲区的大小 (以字节计) (默认 256000)
multithreading 在直接路径中使用多线程
resumable 启用或禁用当前的可恢复会话 (默认 FALSE)
resumable_name 有助于标识可恢复语句的文本字符串
resumable_timeout RESUMABLE 的等待时间 (以秒计) (默认 7200)
date_cache 日期转换高速缓存的大小 (以条目计) (默认 1000)
no_index_errors 出现任何索引错误时中止加载 (默认 FALSE)

15.3.注意事项

命令行参数可以由位置或关键字指定。
前者的例子是 'sqlldr scott/tiger foo';
后这的例子是 'sqlldr control=foo userid=scott/tiger'。
位置指定参数的时间必须早于,
但不可迟于由关键字指定的参数。
例如允许 'sqlldr scott/tiger control=foo logfile=log',
但是不允许 'sqlldr scott/tiger control=foo log',
即使参数 'log' 的位置正确。

15.4.重要参数

rows:
加载的行数,默认值:常规路径:64,直接路径:全部。
常规路径导入时,指定绑定数组中的行数。直
接路径导入时,指一次从数据文件只读取的行数。
该参数同时受bindsize制约,
如果rows每行实际占用大小超出bindsize的最大可用值,
则rows自动降低到bindsize最大可用值。

bindsize:
默认值:256000,以字节为单位。
为绑定数组指定最大可用空间,
用来存储一次读取的rows的记录,
该值不能太小,至少要能放入一条逻辑记录,
不然有可能造成加载失败,
但是设置一个超大值也没有意义,
浪费空间而且起不到任何效果。

direct:
直接路径,默认值是false。
直接路径加载并不是通过insert语句的方式提交数据,
直接路径的加载甚至不走db_buffer,
因为不会存在缓冲区争用,
直接路径加载直接向数据文件写数据,
因此效率较高。

file:
指定写入的表空间数据文件。
通常是并行加载时应该会用到该参数,
指定file文件后,
要加载的内容即只向指定的数据文件写入数据,
通过这种方式某些情况下可以减小磁盘间的竞争。

skip_unusable_indexes:
是否跳过不可用的索引,默认为false。
如果设置为true。在加载数据的时候,
如果没加载的表中索引为unusable,
则该索引数据不维护,数据加载完以后也不会改变索引的状态。
在oracle中也有一个参数叫skip_unusable_indexes,
但是sqlldr中的这个参数优先级比oracle数据库内部的这个参数优先级高。
如果sqlldr中未设置这个参数,则以oracle中的skip_unusable_indexes参数为准。

skip_index_maintenance:
是否跳过索引维护,默认值为false。
该参数仅在直接路径加载时有效,
如果设置为true,则数据加载过程中并不会维护索引,
因此数据加载完后会导致索引无效。

readsize:
缓冲区大小,默认值1048576字节,最大不超过20M。
该参数设置的值仅当从数据文件中读取数据时有效,
如果数据包含在控制文件中则为64K,并不可修改。

streamsize:
流缓冲区大小,默认值是256000字节。
指定直接路径加载时流缓冲区大小。

multithreading:
是否启用多线程。
默认值:多cpu系统默认为true,单cpu的系统默认则为false。
该参数仅仅在直接路径加载时有效。

date_cache:
日期转换缓存,默认值为1000条。
指定一个专门用于日志转换的缓存区,
如果处理的日期在其中,则不需要转换,
否则直接取出来使用。

16.执行结果详细日志

给出loaddata_USER_INFO_direct_parallel.log日志内容,
可以看到导入使用的配置,耗时等详细信息,
供给大家参考:

SQL*Loader: Release 12.1.0.2.0 - Production on Fri Nov 1 11:20:07 2019Copyright (c) 1982, 2014, Oracle and/or its affiliates.  All rights reserved.Control File:   loaddata_USER_INFO_direct_parallel.ctl
Data File:      /home/oracle/USER_INFO.csvBad File:     USER_INFO.badDiscard File:  none specified(Allow all discards)Number to load: ALL
Number to skip: 1
Errors allowed: 999999999
Continuation:    none specified
Path used:      Direct - with parallel option.Table "USER_INFO", loaded from every logical record.
Insert option in effect for this table: APPENDColumn Name                  Position   Len  Term Encl Datatype
------------------------------ ---------- ----- ---- ---- ---------------------
MSISDN                              FIRST     *   ,  O(') CHARACTER
PROVINCE_CODE                        NEXT     *   ,  O(') CHARACTER
CREATE_TIME                          NEXT     *   ,  O(') CHARACTER            SQL string for column : "to_date(:CREATE_TIME, 'yyyy-mm-dd hh24:mi:ss')"SQL*Loader-281: Warning: ROWS parameter ignored in parallel mode.Table "USER_INFO":3 Rows successfully loaded.0 Rows not loaded due to data errors.0 Rows not loaded because all WHEN clauses were failed.0 Rows not loaded because all fields were null.Bind array size not used in direct path.
Column array  rows :   10000
Stream buffer bytes:  256000
Read   buffer bytes:20971520Total logical records skipped:          1
Total logical records read:             3
Total logical records rejected:         0
Total logical records discarded:        0
Total stream buffers loaded by SQL*Loader main thread:        1
Total stream buffers loaded by SQL*Loader load thread:        0Run began on Fri Nov 01 11:20:07 2019
Run ended on Fri Nov 01 11:20:13 2019Elapsed time was:     00:00:05.60
CPU time was:         00:00:00.44

17.参考文章

将CSV文件数据导入Oracle数据库
(sqlldr)将xx.csv文件导入oracle数据库
sqlldr总结参数介绍
Loading data in direct mode and unique index ORA-26026

Oracle数据库导入csv文件(sqlldr命令行)相关推荐

  1. 向oracle中导入*.csv文件

    向oracle中导入*.csv文件 1.什么是*.csv,如何得到? 里面存放的是数据表.每行代表数据库表格的一行, 每行中,每两个数据中间由逗号","分割. *.csv可以通过& ...

  2. oracle数据库导入txt,oracle数据库导入TXT文件方法介绍

    客户端连接数据库导入 1. 安装有oracle客户端,配好监听. 2. 以oracle数据库app用户的表user_svc_info为例 CREATE TABLE USER_SVC_INFO( PHO ...

  3. mysql命令行导入dmp文件_cmd 命令行 imp导入dmp oracle数据库

    简介:  开发者在开发过程中使用到Oracle数据库时,总是避免不了要还原数据库.通常Oracle导出的备份数据库文件为dmp文件.本篇介绍了下怎么导入dmp文件到对应的Oracle数据库中. 步骤一 ...

  4. 达梦数据库导入csv文件

    一.综述 csv文件数据可通过达梦数据库安装自带的dmfldr快速数据装载命令行工具进行导入. 二.前提 创建好需要导入的目标表,我这里是vnap_data_clickhouse模式下的http表. ...

  5. oracle数据库导入导出expdp/impdp命令详细操作过程

    一. 我们为什么现在要用expdp/impdp命令,而不是使用exp/imp命令来备份/还原数据库? expdp/impdp命令,我们也通常称之为"数据泵(DataPump)",它 ...

  6. oracle数据库导入dmp文件

    最近在自己的机子上安装了oracle11g,今天把项目的测试数据库给导入进来了,方便在本地跑起来调试.下面记录一下过程: 1,导出测试数据库的文件; 这个是在公司三楼的一台机子上,用plsql中的工具 ...

  7. oracle数据库导入sql文件

    1.进入到sql文件目录下,登录需要导入文件的用户 打开cmd,输入以下命令,进入oracle, sqlplus username/password username:需要操作的用户名,passwor ...

  8. oracle数据库导入dmp文件,两种方法

    开始的准备工作:前面的步骤都一样 一: 创建表空间: create tablespace root datafile 'D:\Oracle\dataSpace\root.dbf' (你自己的存放空间) ...

  9. Oracle数据库表导出和导入csv文件操作

    Oracle数据库表导出和导入csv文件操作 数据库是Oracle 9i 1.导出csv文件 这个十分简单,用pl/sql工具即可,首先选中要导出的表,右键选择Query data,在左侧出现的窗口中 ...

最新文章

  1. SpringBoot第十四篇:在springboot中用redis实现消息队列
  2. ATM信元的交换方式为?
  3. 【统计学习】假设检验
  4. 使用POI进行数据导出excel时的OOM服务挂掉,cpu飙升的问题
  5. thinkphp如果表名有下划线需要用Model
  6. jstat命令(Java Virtual Machine Statistics Monitoring Tool
  7. 人工智能(15)---宽动态摄像头
  8. Mathpix图片转LaTeX,Word快速插入LaTeX公式教程
  9. qt linux编程思路,关于QT编程入门的那些事
  10. 工程师素质拓展课程主页(2012级)
  11. Mac上使用Chrome浏览器截取长图
  12. 常用的简单的ps快捷键
  13. 苹果开发者App Store绑定连连跨境支付收款教程!
  14. PS的液化功能使用(瘦身,拉长专用)
  15. 陈强老师公开课笔记1——如何区别中介效应、调节效应与交互效应?
  16. Bootstrap(三)可视化布局系统
  17. elasticsearch 出现yellow 分片有unassigned现象原因
  18. PMP项目管理适用于哪些行业?
  19. 可以学习相关框架【转:https://testerhome.com/topics/6283】
  20. js动态加载table,打印table里的内容以及解决打印后的问题

热门文章

  1. h:commandButton
  2. 原生js浏览器兼容性问题
  3. Python3 使用requests请求,解码时出错:'utf8' codec can't decode byte 0x8b in position 1: invalid start byte...
  4. ubuntu server 12.04 jdk,ssh及hadoop配置
  5. 基于visual Studio2013解决C语言竞赛题之1012连接字符串
  6. 准备-上机考试-华为
  7. 【JS】教你如何在对象内任意位置插入任意属性
  8. JAVA实现在线聊天室(层层递进)
  9. Linux驱动(8)--内核编译与配置
  10. 极大似然估计、拉普拉斯平滑定理、M-估计详解