delete相關的pl sql調優

2021-09-22 19:04:04 字數 4610 閱讀 5357

今天開發找到我,說有個問題想徵求一下我的意見。

問題的大體意思是,對目前環境中的兩個表,我們就叫做表a,表b吧,他說根據乙個時間欄位去判斷是否為5天前的記錄,但是這個字段不是索引列欄位。

想問我是否需要新增索引會能極大地提高效能。

對於這個問題沒有肯定的回答,還是取決於資料和表的特性,首先我看了下表a,表b,根據我的印象,這兩個表的資料量都不大,簡單驗證了一下,乙個在300萬,乙個就10萬左右。所以從資料的角度來看,走全表掃瞄也是合理的,不需要再建立乙個索引了,因為新增加的索引可能會對現有的一些sql語句造成印象,還需要做一些評估才可以。

其次,這兩個表都是核心層的表,這種表的結構式不能輕易修改的,表中的索引,結構都是在很多專案中反覆驗證通過的。所以也是不建議直接增加索引的。

開發的同事得到了希望的答案,過一會我就收到了另外一封郵件。

我一看就發現和開發的同事問我的問題有些關聯。

這一段指令碼是做乙個清理相關的操作。最後還嘗試用到了分段提交。

declare

cnt_rec number(13);

tot_rec number(13);

begin

cnt_rec := 0;

tot_rec := 0;

for c1 in (select *from bpm_context_inst

where objid in (select context_inst2context_inst from bpm_proc_inst where objid in

(select /*+ parallel(coll_entity_history 4) */ proc_inst_id from coll_entity_history where end_treatment_date >= sysdate -5 and  end_treatment_date ))

loop

begin

delete from bpm_context_inst t where t.objid = c1.objid;

end;

cnt_rec := cnt_rec + 1;

tot_rec := tot_rec + 1;

if cnt_rec = 100 then

commit;

cnt_rec := 0;

end if;

end loop;

commit;

end;

這段指令碼讓我有些糾結,因為從這個開發同事的角度來看,這段pl/sql指令碼中一旦確定了coll_entity_history

不需要做索引掃瞄,可以走全表掃瞄,他們認為就萬事大吉了。但是我一看到上面的cursor中的那段**,就開始擔心了。

因為他問我的問題似乎還是和這個問題有一定的差距。表bpm_context_inst,bpm_proc_inst這兩個表都是資料量近億的大表。如果從coll_entity_history中得到了太多的資料,外層關聯兩個大表,相比效能也會好不到哪去。如果資料量比較大,直接通過cursor得到快取資料集,做delete還是有一定的效能瓶頸的。對此我也是心有餘悸。可以參見我之前碰到的乙個問題。

如果資料量較大,可以嘗試調優一些這段pl/sql。為了能夠準確地評估這段pl/sql的執**況,我申請從備份庫中匯出了這幾個表的dump,在測試庫中進行測試。

匯出很順利,但是匯入的時候表bpm_context_inst是相當慢,等了半個小時多,還是沒有什麼反應。

以下是通過imp匯入的一些資料,執行了15分鐘的時候,值匯入了60多萬行,按照這個進度,今天是不用幹別的了。

sql> select  620540/15/60 from dual;

620540/15/60

------------

689.488889

按照之前的測試impdp效率也好不到哪去,為什麼呢,我一檢視表結構恍然大悟,原來這個表中含有clob欄位。

好了想模擬測試資料,看來按照目前的情況還是不現實的了。

我們來顯分析一下資料。既然是需要按照每隔5天來做資料的清理,來看看這些天來的資料情況。 以下是我分析得到的近50天來的資料情況,每天的相關資料量其實還是很小的。

65788

2-mar-15

30787

7-feb-15

7987

11-mar-15

33929

6-feb-15

29370

10-feb-15

53211

26-feb-15 62

23-mar-15

3382

17-mar-15

4443

4-mar-15

12095

13-feb-15

8789

12-feb-15

3074

13-mar-15

7598

20-feb-15

2239

8-mar-15

2627

14-mar-15

7726

24-feb-15

6330

22-feb-15

6537

19-feb-15

7158

21-feb-15

2872

7-mar-15

7419

18-feb-15

5104

9-mar-15

46094

27-feb-15

18377

4-feb-15

7571

16-feb-15

4145

6-mar-15

4006

16-mar-15 20

24-mar-15

7578

17-feb-15

29062

9-feb-15

6821

15-feb-15

88618-mar-15

9221

25-feb-15

3822

10-mar-15

95320-mar-15

62115

5-mar-15

2484

15-mar-15

26311

8-feb-15

6997

14-feb-15

16572

28-feb-15 68

26-mar-15

11202

11-feb-15

9251

1-mar-15

5056

22-mar-15

2869

21-mar-15

29508

5-feb-15 1

25-mar-15

49319-mar-15

55572

3-mar-15

7469

23-feb-15

5008

12-mar-15

按照這個資料量,原本存在效能隱患的那段pl/sql看起來也順眼多了。但是細細看來,還是有個硬傷。

就是cursor定義的部分,根據pl/sql的實現目標,沒有用到clob欄位,所以是不相關的。可以在cursor的部分直接過濾掉。

c1 in (select *from bpm_context_inst

where objid in (select context_inst2context_inst from bpm_proc_inst where objid in  (

select /*+ parallel(

coll_entity_history 4) */ proc_inst_id from c

oll_entity_history where end_treatment_date >= sysdate -5 and  end_treatment_date )) 

直接改為select objid from bpm_context_inst就可以了

最後我給出了兩種意見,第一種是上面的pl/sql完全可以通過一句delete語句來完成,至於他們關注的分段提交,其實在這個場景中,影響是忽略不計,實際上一次提交效能還要好於分批提交。

即delete bpm_context_inst

where objid in (select context_inst2context_inst from bpm_proc_inst where objid in 

(select /*+ parallel(coll_entity_history 4) */ proc_inst_id from coll_entity_history where end_treatment_date >= sysdate -5 and  end_treatment_date )

另外一種就是把cursor定義的部分做一些改動,去除clob欄位。對於cursor的提公升是還是很大的。

對於這兩種意見,開發同事說自己確實考慮得不夠周到,不過為了避免給客戶造成更多的困擾,還是選用第二種方案。

這個問題帶給我的啟示就是可能大家問你的問題是乙個場景,但是和另外乙個場景聯絡起來,原來的一些推論就不是那麼肯定了。就比如這個問題中,開發確定不需要索引對於查詢這個表效能影響不大,但是並不意味著在和其他的大表關聯時沒有問題。如果那種情況發生,還需要做一些額外的優化工作。根據資料量最後得知,變更的資料量很小,所以這個也算是化險為夷吧。

PLSQL型別相關操作

1.寫乙個plsql程式,輸出 hello world 字串,語法 dbms output.put line 需要輸出的字串 begin 向sqlplus客戶端工具輸出字串 dbms output.put line hello 你好 end 注意 dbms output是oracle中的乙個輸出物件...

speech to singing相關文章調研

1.speech2singing speech to singing conversion based on boundary equilibrium gan speech to singing sts 的實現方式可以分為兩種 1 model based 用duration module對speec...

生產系統pl sql調優案例 (88天

昨天基本休息了一天,想著生產系統公升級也會多多少少碰到些問題,肯定有一些心得或者是值得學習的東西,結果昨晚到現在生產系統公升級一直為乙個pl sql的問題所困擾。在測試環境中只用了十多分鐘,在生產系統上跑了快5個小時。這個經歷太痛苦了,大半夜還在考慮怎麼優化真是痛苦。首先按照要求清除指定的資料,然後...