乙個insert插入語句很慢的優化

2022-09-09 22:48:20 字數 2514 閱讀 2420

1、insert建議

update表的時候,oracle需要生成redo log和undo log;此時最好的解決辦法是用insert,並且將表設定為nologging;當把表設為nologging後,並且使用的insert時,速度是最快的,這個時候oracle只會生成最低限度的必須的redo log,而沒有一點undo資訊

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

1.insert into tab1 select * fromtab2;

commit;

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

2.alter tabletab1 nologging;

commit;

alter tabletab1 logging;

該方法會使得產生arch大大減少,並且在一定程度上提高時間,根據經驗,千萬級的資料可在45分鐘內完成。但是請注意,該方法適合單程序的序列方式,如果當有多個程序同時執行時,後發起的程序會有enqueue的等待。

注意此方法千萬不能dataguard上用(不過要是在database已經force logging那也是不怕的,呵呵)!!

3.insert into tab1 select /*+ parallel */ * fromtab2;

commit;

對於select之後的語句是全表掃瞄的情況,我們可以加parallel的hint來提高其併發,這裡需要注意的是最大併發度受到初始化引數parallel_max_servers的限制,併發的程序可以通過v$px_session檢視,

或者ps -ef |grep ora_p檢視。

4.alter session set workarea_size_policy=manual;

alter session set sort_area_size=1000000000;

altersession enable parallel dml; 

insert /*+ parallel */ into tab1 select * fromtab2;

commit;

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

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

insert into tab1 select * fromtab2 partition (p2);

insert into tab1 select * fromtab2 partition (p3);

insert into tab1 select * fromtab2 partition (p4);

對於分割槽表可以利用tab1進行多個程序的併發insert,分割槽越多,可以啟動的程序越多。我曾經試過insert2.6億行記錄的乙個表,8個分割槽,8個程序,如果用方法2,單個程序完成可能要40分鐘,

但是由於是有8個分割槽8個程序,後發程序有enqueue,所以因此需要的時間為40分鐘×8;但是如果用方法5,雖然單個程序需要110分鐘,但是由於能夠併發程序執行,所以總共需要的時間就約為110分鐘了。

6.declaretype dtarray is table of varchar2(20) index bybinary_integer;

v_col1 dtarray;

v_col2 dtarray;

v_col3 dtarray;

begin

select col1, col2, col3 bulkcollect

intov_col1, v_col2, v_col3

fromtab2;

forall i in 1 .. v_col1.count

insert into tab1 where tab1.col1 =v_col1;

end;

7.sqlplus -s user/pwdset copycommit 2;

set arraysize 5000;

copy from user/pwd@sid -

to user/pwd@sid -

insert tab1 using select * fromtab2;

exiteof

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

2、分析慢原因

使用10046事件分析

select

*from

table(dbms_xplan.display_cursor('

&sqlid

'));

Sqlite 插入語句 Insert

sqlite 的insert into語句用於向資料庫的某個表中新增新的資料行。基本語法 insert into table name values value1,value2,value3,valuen 插入時,所有欄位都傳值的時候 sqlite insert into tb user value...

Sqlite 插入語句 Insert

sqlite 的insert into語句用於向資料庫的某個表中新增新的資料行。基本語法 insert into table name values value1,value2,value3,valuen 插入時,所有欄位都傳值的時候 sqlite insert into tb user value...

將表資料生成Insert插入語句

參考一下這個 將表資料生成sql指令碼的儲存過程 create procedure dbo.uspoutputdata declare tablename sysname select tablename dbo.sys roleinfo 表名 declare column varchar 1000...