最大的網站源碼資源下載站,
每個數據庫管理員都會面臨數據導入的問題,這有可能發生在數據庫的新老移植過程中,或者是在數據庫崩潰后的恢復重建過程中,還有可能是在創建測試數據庫的模擬環境過程中,總之作為一名合格的數據庫管理員,你應該做好接受各種數據導入請求的技術儲備,同時還要盡量滿足人本能的對導入速度的苛求。本文僅針對 oracle 數據庫所提供的加速數據導入的各種特性和技術進行探討,其中的一些方法也可以轉化應用于其他數據庫。以下七種數據導入方法哪個最適用需要針對具體情況具體分析,我也附帶列舉了影響導入速度的各種因素供斟酌。為了比較各種數據導入方法的效果,我創建了示例表和數據集,并用各種方法導入示例數據集來計算總體導入時間和導入進程占用 cpu 時間,這里得出的時間僅供參考。需要說明的是,建議你使用 oracle 9i 企業版數據庫,當然你也可以嘗試使用 oracle 7.3 以上的標準版數據庫。本文使用的機器配置為:cpu intel p4,內存 256m,數據庫 oracle 9i 企業版。
示例表結構和數據集
為了演示和比較各種數據導入方法,我假定數據導入任務是將外部文件數據導入到 oracle 數據庫的calls表中,外部數據文件包含十萬條呼叫中心記錄,將近 6mb 的文件大小,具體的數據示例如下:
| 82302284384 | 2003-04-18:13:18:58 | 5001 | 投訴 | 手機三包維修質量 |
| 82302284385 | 2003-04-18:13:18:59 | 3352 | 咨詢 | 供水熱線的號碼 |
| 82302284386 | 2003-04-18:13:19:01 | 3142 | 建議 | 增設公交線路 |
接受導入數據的表名是 calls,表結構如下:
| name | null? | type | comment |
| call_id | not null | number | primary key |
| call_date | not null | date | non-unique index |
| emp_id | not null | number | |
| call_type | not null | varchar2(12) | |
| details | not null | varchar2(25) | |
逐條數據插入insert
數據導入的最簡單方法就是編寫 insert 語句,將數據逐條插入數據庫。這種方法只適合導入少量數據,如 sql*plus 腳本創建某個表的種子數據。該方法的最大缺點就是導入速度緩慢,占用了大量的 cpu 處理時間,不適合大批量數據的導入;而其主要優點就是導入構思簡單又有修改完善的彈性,不需要多做其它的準備就可以使用。如果你有很多時間沒法打發,又想折磨一下數據庫和 cpu,那這種方法正適合你。:)
為了與其它方法做比較,現將十萬條記錄通過此方法導入到 calls 表中,總共消耗 172 秒,其中導入進程占用 cpu 時間為 52 秒。
逐條數據插入 insert,表暫無索引
為什么上一種方法占用了較多的 cpu 處理時間,關鍵是 calls 表中已創建了索引,當一條數據插入到表中時,oracle 需要判別新數據與老數據在索引方面是否有沖突,同時要更新表中的所有索引,重復更新索引會消耗一定的時間。因此提高導入速度的好辦法就是在創建表時先不創建索引或者在導入數據之前刪除所有索引,在外部文件數據逐條插入到表中后再統一創建表的索引。這樣導入速度會提高,同時創建的索引也很緊湊而有效,這一原則同樣適用于位圖索引(bitmap index)。對于主要的和唯一的關鍵約束(key constraints),可以使之先暫時失效(disabling)或者刪除約束來獲得同樣的效果,當然這些做法會對已經存在的表的外鍵約束產生相關的影響,在刪除前需要通盤斟酌。
需要說明的是,這種方法在表中已存在很多數據的情況下不太合適。例如表中已有九千萬條數據,而此時需要追加插入一千萬條數據,實際導入數據節省的時間將會被重新創建一億條數據的索引所消耗殆盡,這是我們不希望得到的結果。但是,如果要導入數據的表是空的或導入的數據量比已有的數據量要大得多,那么導入數據節省的時間將會少量用于重新創建索引,這時該方法才可以考慮使用。
加快索引創建是另一個需要考慮的問題。為了減少索引創建中排序的工作時間,可以在當前會話中增加 sort_area_size 參數的大小,該參數允許當前會話在內存的索引創建過程中執行更多的排序操作。同樣還可以使用 nologging 關鍵字來減少因創建索引而生成的 redo 日志量,nologging 關鍵字會對數據庫的恢復和 standby 備用數據庫產生明顯的影響,所以在使用之前要仔細斟酌,到底是速度優先還是穩定優先。
運用這種方法,先刪除 calls 表的主鍵和不唯一的索引,然后逐條導入數據,完成后重新創建索引( 表在導入數據前是空的)。該方法總共消耗 130 秒,包括重建索引的時間,其中導入進程占用 cpu 時間為 35秒。
這種方法的優點是可以加快導入的速度并使索引更加緊湊有效;缺點是缺乏通用性,當你對表增加新的復雜的模式元素(索引、外鍵等)時你需要添加代碼、修改導入執行程序。另外針對 7*24 在線要求的數據庫在線導入操作時,刪除表的索引會對在線用戶的查詢有很大的性能影響,同時也要考慮,主要或唯一的關鍵約束條件的刪除或失效可能會影響到引用它們的外鍵的使用。
批量插入,表暫無索引
在oracle v6 中 oci 編程接口加入了數組接口特性。數組操作允許導入程序讀取外部文件數據并解析后,向數據庫提交sql語句,批量插入 sql 語句檢索出的數據。oracle 僅需要執行一次 sql 語句,然后在內存中批量解析提供的數據。批量導入操作比逐行插入重復操作更有效率,這是因為只需一次解析 sql 語句,一些數據綁訂操作以及程序與數據庫之間來回的操作都顯著減少,而且數據庫對每一條數據的操作都是重復可知的,這給數據庫提供了優化執行的可能。其優點是數據導入的總體時間明顯減少,特別是進程占用 cpu 的時間。
需要提醒的是,通過 oci 接口確實可以執行數據批量導入操作,但是許多工具和腳本語言卻不支持使用此功能。如果要使用該方法,需要研究你所使用的開發工具是否支持 oci 批量操作功能。導入程序需要進行復雜的編碼并可能存在錯誤的風險,缺乏一定的彈性。
運用上述方法,程序將外部數據提取到內存中的數組里,并執行批量插入操作(100行/次),保留了表的刪除/重建索引操作,總的導入時間下降到 14 秒,而進程占用 cpu 的時間下降到7秒,可見實際導入數據所花費的時間顯著下降了 95%。
create table as select,使用oracle9i的external table
oracle 9i 的一項新特性就是 external table,它就象通常的數據庫表一樣,擁有字段和數據類型約束,并且可以查詢,但是表中的數據卻不存儲在數據庫中,而是在與數據庫相關聯的普通外部文件里。當你查詢 external table 時,oracle 將解析該文件并返回符合條件的數據,就象該數據存儲在數據庫表中一樣。
主站蜘蛛池模板:
重庆市|
讷河市|
湘阴县|
大厂|
望城县|
宁南县|
和静县|
合肥市|
岱山县|
二手房|
新昌县|
吴桥县|
河东区|
南丰县|
扎囊县|
论坛|
宜黄县|
綦江县|
枣强县|
宁晋县|
汪清县|
隆化县|
黑龙江省|
那坡县|
临沧市|
修文县|
广平县|
弥勒县|
光泽县|
宁蒗|
夹江县|
云霄县|
台中市|
洛阳市|
灵武市|
长乐市|
南阳市|
九龙坡区|
山阳县|
青河县|
钟祥市|