使用SQLload大批量导入数据
第一步:创建表
CREATE TABLE "TESTHT"."DEMO"
(
"ID" VARCHAR2(20 BYTE) NOT NULL ENABLE,
"NAME" VARCHAR2(20 BYTE),
"AGE" VARCHAR2(20 BYTE)
)
第二步 : 编写sqlload导入数据的控制文件,这里测试的控制文件如下,可以根据自己需要添加相关的控制参数,测试的话复制保存为txt文件即可!
创建控制文件 : /home/demo.ctl
内容如下:
OPTIONS (rows=1024)
LOAD DATA
CHARACTERSET ZHS16GBK -- 这里不加的话,可能中文乱码
INFILE '/home/demo.txt'
truncate
INTO TABLE DEMO
Fields terminated by ","
Optionally enclosed by '"'
trailing nullcols
(
ID,
NAME,
AGE
)
控制文件还有其他参数,根据自己需求调整和测试:
附部分控制参数:具体用法以官方文档为准
OPTIONS (skip=1,rows=128) -- sqlldr 命令显示的选项可以写到这里边来,skip=1 用来跳过数据中的第一行
LOAD DATA
INFILE "users_data.csv" --指定外部数据文件,可以是不同格式的数据文件,如csv、txt都支持 可以写多个 INFILE "another_data_file.csv" 指定多个数据文件
truncate --操作类型,用 truncate table 来清除表中原有记录,根据情况而定是否需要清楚原有表中数据
INTO TABLE users --要插入记录的表
when user_id<>'1' -- 还可以用 when 子 句选择导入符合条件的记录
Fields terminated by "," --数据中每行记录用 "," 分隔
Optionally enclosed by '"' --数据中每个字段用 '"' 框起,比如字段中有 "," 分隔符时
trailing nullcols --表的字段没有对应的值时允许为空
(
virtual_column FILLER, --这是一个虚拟字段,用来跳过由 PL/SQL Developer 生成的第一列序号
user_id number, --字段可以指定类型,否则认为是 CHARACTER 类型, log 文件中有显示
username "'Hi '||upper(:username)",--,还能用SQL函数或运算对数据进行加工处理
logintimes terminated by "," NULLIF (logintimes='NULL') --可为列单独指定分隔符
last_login DATE "YYYY-MM-DD HH24:MI:SS" NULLIF (last_login="NULL") --当字段为"NULL"时就是 NULL
)
insert --为缺省方式,在数据装载开始时要求表为空
append --在表中追加新记录
replace --删除旧记录(用 delete from table 语句),替换成新装载的记录
truncate --删除旧记录(用 truncate table 语句),替换成新装载的记录
第三步 : 创建需要导入的数据,注意数据格式必须和表结构严格对应,否则导入失败!测试数据如下:有部分数据最后字段为空,所以控制文件中需要加trailing nullcols 参数!
创建数据文件 : /home/demo.txt
"2019-01-20","李思","23",
"2019-01-20","李思","23",
"2019-01-20","李思","23",
"2019-01-20","李思","23",
"2019-01-20","李思","23",
"2019-01-20","李思","23",
"2019-01-20","李思","23",
"2019-01-20","李思","23",
"2019-01-20","李思","23",
"2019-01-20","李思","23",
"2019-01-20","李思","23",
"2019-01-20","李思","23",
第四步 : 执行
我的数据文件数据是300万条记录, 经测试执行时间大概在7s左右, 常规导入可以通过使用 INSERT语句来导入数据。Direct导入可以跳过数据库的相关逻辑(DIRECT=TRUE),而直接将数据导入到数据文件中,可以提高导入数据的 性能。当然,在很多情况下,不能使用此参数(如果主键重复的话会使索引的状态变成UNUSABLE!)。
[oracle@HM311 home]$ sqlldr testht/123456 control=/home/demo.ctl data=/home/demo.txt direct=true;
.......
Commit point reached - logical record count 2999760
Commit point reached - logical record count 2999824
Commit point reached - logical record count 2999888
Commit point reached - logical record count 2999952
Commit point reached - logical record count 2999999
Commit point reached - logical record count 3000000
sqlLoad语法结构:
userid -- ORACLE 用户名/口令
control -- 控制文件名
log -- 记录导入时的日志文件,默认为 控制文件(去除扩展名).log
bad -- 坏数据文件,默认为 控制文件(去除扩展名).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)本文来自:雨花石,原地址:https://www.yuhuashi.infohttps://www.yuhuashi.info/post/121.html
当加载大量数据时(大约超过10GB),最好抑制日志的产生:
SQL>ALTER TABLE DEMO nologging;