使用insert插入大量數據的個人經驗總結

這篇論壇文章根據筆者的個人經驗著重介紹了使用insert插入大量數據的常用技巧,更多內容請參考下文:

在很多時候,我們會需要對一個表進行插入大量的數據,並且希望在盡可能短的時間內完成該工作,這裏,和大家分享下我平時在做大量數據insert的一些經驗。

前提:在做insert數據之前,如果是非生産環境,請將表的索引和約束去掉,待insert完成後再建索引和約束。

1.insert into tab1 select * from tab2;

commit;

這是最基礎的insert語句,我們把tab2表中的數據insert到tab1表中。根據經驗,千萬級的數據可在1小時內完成。但是該方法産生的arch會非常快,需要關注歸檔的産生量,及時啓動備份軟件,避免arch目錄撐爆。

2.alter table tab1 nologging;

insert /*+ append */ into tab1 select * from tab2;

commit;

alter table tab1 logging;

該方法會使得産生arch大大減少,並且在一定程度上提高時間,根據經驗,千萬級的數據可在45分鍾內完成。但是請注意,該方法適合單進程的串行方式,如果當有多個進程同時運行時,後發起的進程會有enqueue的等待。注意此方法千萬不能dataguard上用(不過要是在database已經force logging那也是不怕的,呵呵)!!

3.insert into tab1 select /*+ parallel */ * from tab2;

commit;

對于select之後的語句是全表掃描的情況,我們可以加parallel的hint來提高其並發,這裏需要注意的是最大並發度受到初始化參數parallel_max_servers的限制,並發的進程可以通過v$px_session查看,或者ps -ef |grep ora_p查看。

4.alter session enable parallel dml;

insert /*+ parallel */ into tab1 select * from tab2;

commit;

與方法2相反,並發的insert,尚未比較和方法2哪個效率更高(偶估計是方法2快),有測試過的朋友歡迎補充。

5.insert into tab1 select * from tab2 partition (p1);

insert into tab1 select * from tab2 partition (p2);

insert into tab1 select * from tab2 partition (p3);

insert into tab1 select * from tab2 partition (p4);

對于分區表可以利用tab1進行多個進程的並發insert,分區越多,可以啓動的進程越多。我曾經試過insert 2.6億行記錄的一個表,8個分區,8個進程,如果用方法2,單個進程完成可能要40分鍾,但是由于是有8個分區8個進程,後發進程有enqueue,所以因此需要的時間爲40分鍾×8;但是如果用方法5,雖然單個進程需要110分鍾,但是由于能夠並發進程執行,所以總共需要的時間就約爲110分鍾了。

6. DECLARE

TYPE dtarray IS TABLE OF VARCHAR2(20) INDEX BY BINARY_INTEGER;

v_col1 dtarray;

v_col2 dtarray;

v_col3 dtarray;

BEGIN

SELECT col1, col2, col3 BULK COLLECT

INTO v_col1, v_col2, v_col3

FROM tab2;

FORALL i IN 1 .. v_col1.COUNT

insert into tab1 WHERE tab1.col1 = v_col1;

END;

用批量綁定(bulk binding)的方式。當循環執行一個綁定變量的sql語句時候,在PL/SQL 和SQL引擎(engines)中,會發生大量的上下文切換(context switches)。使用bulk binding,能將數據批量的從plsql引擎傳到sql引擎,從而減少上下文切換過程,提升效率。該方法比較適合于在線處理,不必停機。

7.sqlplus -s user/pwd< runlog.txt

set copycommit 2;

set arraysize 5000;

copy from user/pwd@sid -

to user/pwd@sid -

insert tab1 using select * from tab2;

exit

EOF

用copy的方法進行插入,注意此處insert沒有into關鍵字。該方法的好處是可以設置copycommit和arrarysize來一起控制commit的頻率,上面的方法是每10000行commit一次。

個人經驗總結:DB2數據庫邏輯卷的複制
這篇論壇文章(賽迪網技術社區)著重介紹了DB2數據庫邏輯卷的複制,詳細內容請參考下文: 周末加班,需要把db2的instance和數據遷移到datavg下(原來的“DBA”給部署到rootvg下了......所以在這裏我在DBA前後都加了引...查看完整版>>個人經驗總結:DB2數據庫邏輯卷的複制
 
個人經驗總結:MySQL數據庫優化技巧集錦
一、我們可以且應該優化什麽? 硬件 操作系統/軟件庫 SQL服務器(設置和查詢) 應用編程接口(API) 應用程序 二、優化硬件 如果你需要龐大的數據庫表(>2G),你應該考慮使用64位的硬件結構,像Alpha、Sparc或即將推出...查看完整版>>個人經驗總結:MySQL數據庫優化技巧集錦
 
個人經驗總結:完全卸載MySQL數據庫5.0
這篇論壇文章(賽迪網技術社區)詳細介紹了完全卸載MySQL數據庫5.0的具體方法,更多內容請參考下文: 數據庫突然出了問題,沒辦法只能重裝,因爲事先並不知道MySQL卸載是比較複雜的,結果重新安裝的時候出現了問題:...查看完整版>>個人經驗總結:完全卸載MySQL數據庫5.0
 
個人經驗總結:Sybase數據庫性能優化
這篇論壇文章(賽迪網技術社區)用一個實例講解了Sybase數據庫性能優化的具體過程,具體內容請參考下文: 共享鎖 sp_getapplock 鎖定應用程序資源 sp_releaseapplock 爲應用程序資源解鎖 SET LOCK_TIMEOUT 1800 鎖超...查看完整版>>個人經驗總結:Sybase數據庫性能優化
 
更新、插入數據庫所使用的UPDATE()
<%@ Page Language="C#" EnableSessionState="False" %><%@ Import Namespace="System" %><%@ Import Namespace="System.Data" %><%@ Import Namespace="System.Data.OleDb" %><%@ Impor...查看完整版>>更新、插入數據庫所使用的UPDATE()
 
更新、插入數據庫所使用的UPDATE()
<%@ Page Language="C#" EnableSessionState="False" %><%@ Import Namespace="System" %><%@ Import Namespace="System.Data" %><%@ Import Namespace="System.Data.OleDb" %><%@ Impor...查看完整版>>更新、插入數據庫所使用的UPDATE()
 
個人經驗總結:Oracle數據庫SCN號詳解
Oracle數據庫SCN號詳解: 系統檢查點scn(v$database(checkpoint_change#)) 數據文件檢查點(v$datafile(checkpoint_change#)) 數據文件終止scn(v$datafile(last_change#)) 數據文件中存放的檢查點 啓動scn (v$datafi...查看完整版>>個人經驗總結:Oracle數據庫SCN號詳解
 
個人經驗總結:處理海量數據的經驗和技巧
在實際的工作環境下,許多人會遇到海量數據這個複雜而艱巨的問題,它的主要難點有以下幾個方面: 一、數據量過大,數據中什麽情況都可能存在。 如果說有10條數據,那麽大不了每條去逐一檢查,人爲處理,如果有上百條...查看完整版>>個人經驗總結:處理海量數據的經驗和技巧
 
個人經驗總結:DB2數據庫技術關鍵領域列表
許多技術人員可以輕松地討論db2技術的細節,很自信地談論查詢並行化、數據壓縮、WebSphere MQ 集成、大對象管理、JDBC 和 ADO.Net 驅動程序、大型機 Parallel Sysplex 上的數據共享、DB2 for Linux, Unix, and windo...查看完整版>>個人經驗總結:DB2數據庫技術關鍵領域列表
 
 
回到王朝網路移動版首頁