環境:
服務端:RHEL6.4 + Oracle 11.2.0.4
客戶端:WIN10 + Oracle 11.2.0.1 client
目錄:
1. sqlldr語法
``` 用法: SQLLDR keyword=value [,keyword=value,...]有效的關鍵字:
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)
PLEASE NOTE: 命令行參數可以由位置或關鍵字指定
。前者的例子是 'sqlldr
scott/tiger foo'; 后一種情況的一個示例是 'sqlldr control=foo
userid=scott/tiger'。位置指定參數的時間必須早於
但不可遲於由關鍵字指定的參數。例如,
允許 'sqlldr scott/tiger control=foo logfile=log', 但是
不允許 'sqlldr scott/tiger control=foo log', 即使
參數 'log' 的位置正確。
<h1 id="2">2. sqlldr實驗准備</h1>
## 2.1 模擬構建導入的源文件 ##
select count(*) from dba_objects;
getobject.sql(利用兩表關聯無連接條件,由於笛卡兒積產生百萬數量級結果集)
select a.owner||',"'||a.object_name||'",'||a.object_id||','||to_char(a.created, 'yyyy-mm-dd hh24:mi:ss')||','||a.status from dba_objects a, (select rownum rn from dual connect by rownum<=20) b;
call.sql
set echo off
set term off
set linesize 140 pagesize 0
set feedback off
set heading off
spool E:\jingyu\scripts\ldr_object.csv
@E:\jingyu\scripts\getobject.sql
spool off
set heading on
set feedback on
set term on
set echo on
SQL調用腳本生成源文件
@E:\jingyu\scripts\call.sql
我這里得到了一個234M大小的ldr_object.csv文件,最后一列有空行,可以考慮先數據清洗后再導入。
## 2.2 創建表 ##
create table objects(
owner varchar2(30),
object_name varchar2(50),
object_id number,
status varchar2(10),
created date
);
create index idx_obj_owner_name on objects(owner, object_name);
## 2.3 控制文件ldr_object.ctl ##
load data
infile "E:\jingyu\scripts\ldr_object.csv"
truncate into table objects
fields terminated by "," optionally enclosed by ' ' TRAILING NULLCOLS
(owner,
object_name,
object_id,
created "to_date(:created,'yyyy-mm-dd hh24:mi:ss')",
status "trim(:status)"
)
這里沒有處理源文件的行尾空格,所以用到了trim函數對最后一列進行處理,當然還是建議在加載前就進行源文件的格式處理。
<h1 id="3">3. sqlldr常規加載</h1>
sqlldr jingyu/jingyu@db1 control=E:\jingyu\scripts\ldr_object.ctl bad=E:\jingyu\scripts\ldr_object1.bad log=E:\jingyu\scripts\ldr_object1.log skip=0 errors=9999
對應log文件:
SQL*Loader: Release 11.2.0.1.0 - Production on 星期一 9月 21 10:58:39 2015
Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights reserved.
控制文件: E:\jingyu\scripts\ldr_object.ctl
數據文件: E:\jingyu\scripts\ldr_object.csv
錯誤文件: E:\jingyu\scripts\ldr_object1.bad
廢棄文件: 未作指定
(可廢棄所有記錄)
要加載的數: ALL
要跳過的數: 0
允許的錯誤: 9999
綁定數組: 64 行, 最大 256000 字節
繼續: 未作指定
所用路徑: 常規
表 OBJECTS,已加載從每個邏輯記錄
插入選項對此表 TRUNCATE 生效
TRAILING NULLCOLS 選項生效
列名 位置 長度 中止 包裝數據類型
OWNER FIRST * , O ( ) CHARACTER
OBJECT_NAME NEXT * , O ( ) CHARACTER
OBJECT_ID NEXT * , O ( ) CHARACTER
CREATED NEXT * , O ( ) CHARACTER
列的 SQL 串: "to_date(:created,'yyyy-mm-dd hh24:mi:ss')"
STATUS NEXT * , O ( ) CHARACTER
列的 SQL 串: "trim(:status)"
表 OBJECTS:
1731340 行 加載成功。
由於數據錯誤, 0 行 沒有加載。
由於所有 WHEN 子句失敗, 0 行 沒有加載。
由於所有字段都為空的, 0 行 沒有加載。
為綁定數組分配的空間: 82560 字節 (64 行)
讀取 緩沖區字節數: 1048576
跳過的邏輯記錄總數: 0
讀取的邏輯記錄總數: 1731340
拒絕的邏輯記錄總數: 0
廢棄的邏輯記錄總數: 0
從 星期一 9月 21 10:58:39 2015 開始運行
在 星期一 9月 21 11:12:20 2015 處運行結束
經過時間為: 00: 13: 41.34
CPU 時間為: 00: 01: 51.13
13分41秒加載完成1731340記錄數。
<h1 id="4">4. sqlldr常規加載優化</h1>
sqlldr jingyu/jingyu@db1 control=E:\jingyu\scripts\ldr_object.ctl bad=E:\jingyu\scripts\ldr_object2.bad log=E:\jingyu\scripts\ldr_object2.log skip=0 errors=9999 rows=5000 bindsize=20971520 readsize=20971520
對應log文件:
SQL*Loader: Release 11.2.0.1.0 - Production on 星期一 9月 21 11:17:26 2015
Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights reserved.
控制文件: E:\jingyu\scripts\ldr_object.ctl
數據文件: E:\jingyu\scripts\ldr_object.csv
錯誤文件: E:\jingyu\scripts\ldr_object2.bad
廢棄文件: 未作指定
(可廢棄所有記錄)
要加載的數: ALL
要跳過的數: 0
允許的錯誤: 9999
綁定數組: 5000 行, 最大 20971520 字節
繼續: 未作指定
所用路徑: 常規
表 OBJECTS,已加載從每個邏輯記錄
插入選項對此表 TRUNCATE 生效
TRAILING NULLCOLS 選項生效
列名 位置 長度 中止 包裝數據類型
OWNER FIRST * , O ( ) CHARACTER
OBJECT_NAME NEXT * , O ( ) CHARACTER
OBJECT_ID NEXT * , O ( ) CHARACTER
CREATED NEXT * , O ( ) CHARACTER
列的 SQL 串: "to_date(:created,'yyyy-mm-dd hh24:mi:ss')"
STATUS NEXT * , O ( ) CHARACTER
列的 SQL 串: "trim(:status)"
表 OBJECTS:
1731340 行 加載成功。
由於數據錯誤, 0 行 沒有加載。
由於所有 WHEN 子句失敗, 0 行 沒有加載。
由於所有字段都為空的, 0 行 沒有加載。
為綁定數組分配的空間: 6450000 字節 (5000 行)
讀取 緩沖區字節數:20971520
跳過的邏輯記錄總數: 0
讀取的邏輯記錄總數: 1731340
拒絕的邏輯記錄總數: 0
廢棄的邏輯記錄總數: 0
從 星期一 9月 21 11:17:26 2015 開始運行
在 星期一 9月 21 11:19:43 2015 處運行結束
經過時間為: 00: 02: 17.92
CPU 時間為: 00: 00: 35.25
加載速度從13分41秒提升到2分17秒。因為默認一次加載從64行改為5000行,同時增大了bindsize的值為20971520(20M),實際5000行使用了6M左右的空間,所以表數據量大的情況下,還可以繼續加大rows的參數值,具體效率提升情況還是需要具體的測試才可以最終選擇合適的值。
<h1 id="5">5. sqlldr直接路徑加載</h1>
sqlldr jingyu/jingyu@db1 control=E:\jingyu\scripts\ldr_object.ctl bad=E:\jingyu\scripts\ldr_object3.bad log=E:\jingyu\scripts\ldr_object3.log skip=0 errors=9999 rows=10000 direct=true
對應log文件:
SQL*Loader: Release 11.2.0.1.0 - Production on 星期一 9月 21 11:33:10 2015
Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights reserved.
控制文件: E:\jingyu\scripts\ldr_object.ctl
數據文件: E:\jingyu\scripts\ldr_object.csv
錯誤文件: E:\jingyu\scripts\ldr_object3.bad
廢棄文件: 未作指定
(可廢棄所有記錄)
要加載的數: ALL
要跳過的數: 0
允許的錯誤: 9999
繼續: 未作指定
所用路徑: 直接
表 OBJECTS,已加載從每個邏輯記錄
插入選項對此表 TRUNCATE 生效
TRAILING NULLCOLS 選項生效
列名 位置 長度 中止 包裝數據類型
OWNER FIRST * , O ( ) CHARACTER
OBJECT_NAME NEXT * , O ( ) CHARACTER
OBJECT_ID NEXT * , O ( ) CHARACTER
CREATED NEXT * , O ( ) CHARACTER
列的 SQL 串: "to_date(:created,'yyyy-mm-dd hh24:mi:ss')"
STATUS NEXT * , O ( ) CHARACTER
列的 SQL 串: "trim(:status)"
表 OBJECTS 的以下索引已處理:
索引 JINGYU.IDX_OBJ_OWNER_NAME 已成功加載, 具有 1731340 個關鍵字
表 OBJECTS:
1731340 行 加載成功。
由於數據錯誤, 0 行 沒有加載。
由於所有 WHEN 子句失敗, 0 行 沒有加載。
由於所有字段都為空的, 0 行 沒有加載。
在直接路徑中沒有使用綁定數組大小。
列數組 行數: 5000
流緩沖區字節數: 256000
讀取 緩沖區字節數: 1048576
跳過的邏輯記錄總數: 0
讀取的邏輯記錄總數: 1731340
拒絕的邏輯記錄總數: 0
廢棄的邏輯記錄總數: 0
由 SQLLoader 主線程加載的流緩沖區總數: 581
由 SQLLoader 加載線程加載的流緩沖區總數: 669
從 星期一 9月 21 11:33:10 2015 開始運行
在 星期一 9月 21 11:35:24 2015 處運行結束
經過時間為: 00: 02: 13.92
CPU 時間為: 00: 00: 23.92
sqlldr直接路徑加載速度提升到2分13秒。
**注意:**直接路徑加載過程中,索引會變成unusable狀態,加載完成后變為valid狀態。
直接路徑加載過程中,查看索引狀態為UNUSABLE。
SQL> select table_name, index_name, status from user_indexes where table_name='OBJECTS';
TABLE_NAME INDEX_NAME STATUS
OBJECTS IDX_OBJ_OWNER_NAME UNUSABLE
直接路徑加載完成,查看索引狀態為VALID。
SQL> select table_name, index_name, status from user_indexes where table_name='OBJECTS';
TABLE_NAME INDEX_NAME STATUS
OBJECTS IDX_OBJ_OWNER_NAME VALID
<h1 id="6">6. sqlldr直接路徑加載優化</h1>
針對streamsize,date_cache兩個參數,參數具體含義見第一部分的幫助。
sqlldr jingyu/jingyu@db1 control=E:\jingyu\scripts\ldr_object.ctl bad=E:\jingyu\scripts\ldr_object4.bad log=E:\jingyu\scripts\ldr_object4.log skip=0 errors=9999 rows=10000 direct=true streamsize=10485760 date_cache=5000
對應log文件:
SQL*Loader: Release 11.2.0.1.0 - Production on 星期一 9月 21 11:58:35 2015
Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights reserved.
控制文件: E:\jingyu\scripts\ldr_object.ctl
數據文件: E:\jingyu\scripts\ldr_object.csv
錯誤文件: E:\jingyu\scripts\ldr_object4.bad
廢棄文件: 未作指定
(可廢棄所有記錄)
要加載的數: ALL
要跳過的數: 0
允許的錯誤: 9999
繼續: 未作指定
所用路徑: 直接
表 OBJECTS,已加載從每個邏輯記錄
插入選項對此表 TRUNCATE 生效
TRAILING NULLCOLS 選項生效
列名 位置 長度 中止 包裝數據類型
OWNER FIRST * , O ( ) CHARACTER
OBJECT_NAME NEXT * , O ( ) CHARACTER
OBJECT_ID NEXT * , O ( ) CHARACTER
CREATED NEXT * , O ( ) CHARACTER
列的 SQL 串: "to_date(:created,'yyyy-mm-dd hh24:mi:ss')"
STATUS NEXT * , O ( ) CHARACTER
列的 SQL 串: "trim(:status)"
表 OBJECTS 的以下索引已處理:
索引 JINGYU.IDX_OBJ_OWNER_NAME 已成功加載, 具有 1731340 個關鍵字
表 OBJECTS:
1731340 行 加載成功。
由於數據錯誤, 0 行 沒有加載。
由於所有 WHEN 子句失敗, 0 行 沒有加載。
由於所有字段都為空的, 0 行 沒有加載。
在直接路徑中沒有使用綁定數組大小。
列數組 行數: 5000
流緩沖區字節數:10485760
讀取 緩沖區字節數: 1048576
跳過的邏輯記錄總數: 0
讀取的邏輯記錄總數: 1731340
拒絕的邏輯記錄總數: 0
廢棄的邏輯記錄總數: 0
由 SQLLoader 主線程加載的流緩沖區總數: 581
由 SQLLoader 加載線程加載的流緩沖區總數: 0
從 星期一 9月 21 11:58:35 2015 開始運行
在 星期一 9月 21 12:00:42 2015 處運行結束
經過時間為: 00: 02: 07.63
CPU 時間為: 00: 00: 29.36
速度提升到2分7秒。
<h1 id="7">References</h1>
- 塗抹 Oracle[M]. 中國水利水電出版社, 2010.
