SQL優化之六脈神劍

lhrbest發表於2016-04-13

DBAplus社群 | 2016-02-03 07:47

wpsFE96.tmp

本文作者通過身邊的案例,詳細闡述了SQL優化過程中的種種方法和小竅門,內容豐富且言之有物,希望能讓接觸到SQL的同學可以體會到SQL提速的樂趣!

1.前言

關於SQL優化,前輩們、技術大咖們、各個技術論壇上早就有很多的優秀文章,今番我再次提起,心情忐忑,實在是有些班門弄斧和自不量力了。

在大家的鼓勵下我想寫一下也好,就寫我們身邊的事,用身邊的案例來演繹SQL優化,用形象語言把SQL優化說成我們身邊的事,希望能讓接觸到SQL的同學可以體會到SQL提速的樂趣!

2.理解幾個名詞

提到SQL優化,我們不得不學習幾個名詞,這就好比武俠小說裡練習武功一樣,不知道幾個穴道,不瞭解幾個氣門都不好意思提自己是練功夫的。名詞挺多,除了這裡提到的還有好多,比如內外連線、巢狀迴圈、遊標共享、繫結變數、軟硬解析等等,武功太多,練不過來,那我們先把馬步紮好再說。沒有提到的功夫在藏經閣都有,請按需百度。

2.1 執行計劃

執行計劃是什麼呢?就是SQL執行的路徑和執行步驟。怎麼理解呢?你從家裡到公司可以選擇開車走高速,也可以選擇做公交車走市區街道,那麼你選擇用哪個交通工具,走哪個路線,就是你的執行計劃。但是一次只能有一個方案。

一個SQL生成了執行計劃,他就會被固定到共享池裡,只有在表發生了變更、統計資訊過舊、共享池被重新整理、資料庫重啟等情況下SQL才會重新生成執行計劃。還是從家到公司,城市在修路,公交路線變化都會影響你選擇什麼樣的方式上班。

2.2 索引

索引是一個單獨的、物理的資料庫結構,它是某個表中一列或若干列值的集合和相應的指向表中物理標識這些值的資料頁的邏輯指標清單。怎麼理解呢?表是一本書,索引就是這本書的目錄。

2.3 統計資訊

統計資訊主要是描述資料庫中表,索引的大小、規模、資料分佈狀況等的一類資訊。比如表的行數、塊數、平均每行的大小、索引的leaf blocks、索引欄位的行數、不同值的大小等,都屬於統計資訊。

Oracle的基於成本的優化器(還有一種是基於規則的,武功過時了,不練了)正是根據這些統計資訊資料,計算出不同訪問路徑下,不同連線方式下,各種計劃的成本,最後選擇出成本最小的計劃。如果沒有統計資訊呢?會發生動態取樣,就是在生產執行計劃前去表、索引去進行資料取樣。

怎麼理解呢?還是從家到公司,有了地圖和公交資訊,高速收費情況等資訊,大家就可以選擇最合適的上班方案了。沒有這些現成的資訊你就需要實際去調研一下了,比較麻煩,而且可能造成不合適的選擇。

3.某個SQL是否能優化?

怎麼能確定一個SQL是否能優化呢?這個不太好回答,DBA們經常說先分析分析看看。那麼分析什麼呢:現在效率如何?執行計劃?跑的時候等待事件?表多大?選擇列上有無索引?選擇性如何?有統計資訊?連線方式?......又是這些名詞,還沒有完全理解的小夥伴不要著急,我不是賣野藥的,馬上就要表演啦!

其實呢,也可以不用這麼複雜。一個非常劣質的SQL(跑幾十分鐘,甚至是幾個小時的SQL)最終能不能有質的提速,主要就是看業務的本質上需要訪問多少資料量,如果業務本質上需要訪問的資料量越少,一般來講提速餘地就越大。簡單吧,所以一個業務專家,你遇到了一個劣質SQL,不用DBA分析,你應該就知道有沒有優化餘地了。

怎麼理解呢?一個大操場上有一個紅色的玻璃球,讓你去拿到,你沒看見,地毯式的找半天,有人給你個座標圖,你10秒鐘跑過去就找到了,這就是有提速餘地,如果滿操場上都是需要的紅色玻璃球讓你拿,無論怎麼拿,都要拿半天,這就是沒法有質的飛躍(就是沒辦法幾秒鐘、幾分鐘把活幹完)。

下面我們循序漸進的講一些案例吧。

01第一劍少商劍:合理利用索引

1.1利用索引提高效率

INS_USER_571 表上有兩個索引IDX_INS_USER1_571,IDX_INS_USER2_571分別對應列BILL_ID,EXPIRE_DATE列,SQL 和執行計劃:

select * from SO1.INS_USER_571 M where M.BILL_ID = '13905710000' and M.EXPIRE_DATE > sysdate;

wpsFE97.tmp

符合BILL_ID的資料只有一條,而符合EXPIRE_DATE條件的資料有幾萬條,就是說BILL_ID選擇性好,選擇IDX_INS_USER1_571索引就會更快的找到這條資料。

怎麼理解?大操場上找1個玻璃球,給你兩個座標圖,一張直接告訴你這個玻璃球的具體位置,一張圖告訴你在某個10米的範圍圈內,選擇哪個呢?肯定選第一張。

1.2走索引反而慢?

在CREATE_DATE上建立個索引IDX_INS_USER4_571:

SQL:

SELECT COUNT(*) FROM SO1.INS_USER_571 M WHERE M.CREATE_DATE >= TO_DATE('20110101','YYYYMMDD') AND M.CUST_TYPE='1';

PLAN:沒有走索引?!

wpsFE98.tmp

難道是優化器有問題?測試下就知道了。為了明確加Hints測試:

SELECT /*+full(M)*/COUNT(*) FROM SO1.INS_USER_571 M WHERE M.CREATE_DATE >= TO_DATE('20110101','YYYYMMDD') AND M.CUST_TYPE='1';

SELECT /*+INDEX(M,IND_INS_USRE4_571)*/COUNT(*) FROM SO1.INS_USER_571 M WHERE M.CREATE_DATE >= TO_DATE('20110101','YYYYMMDD') AND M.CUST_TYPE='1';

wpsFEA9.tmp

wpsFEAA.tmp

看來優化器沒有錯!

當需要掃描的資料量較大時,走索引的成本比全表掃描的成本還要高。

怎麼理解?一本書1000頁,其中800頁的內容都是你需要的,那你看書的時候就沒有必要每看一頁都要回過頭來翻翻目錄了,這樣多羅嗦呀!直接順序往下讀好了。

1.3本招的幾個口訣

在where條件中選擇列上加了函式,沒法利用索引

例如:whereto_char(create_date,’YYYY-MM-DD HH24:MI:SS’)>= ‘2015-04-08 00:00:00’

這樣沒法利用到create_date的索引

正確的寫法:

wherecreate_date>=to_date( ‘2015-04-08 00:00:00’,’YYYY-MM-DD HH24:MI:SS’)

案例:select count(t.visitor_id) as pv

from t_stat_logbase t

where instr(t.visit_url, :""SYS_B_0"")>:""SYS_B_1"" and

to_char(t.visit_date,:""SYS_B_2"")=:""SYS_B_3""

visit_url, visit_date都有索引,而且visit_url列的選擇性非常好,但是因為在本列上加了instr的函式,造成只能全表掃描,因每天零點左右執行頻率高,資料庫經常出現效能告警,應用改造後有效利用了索引,資料庫恢復正常。

?變數型別要正確,避免隱式轉換造成沒法利用索引

Bill_Id是varchar2的型別

Where bill_id=1就沒法利用索引。

?Where條件終須用到前導列才能走上組合索引,組合索引中選擇性好的要放在前面:

索引ind_ins_user5_571(create_date, cust_type): where cust_type =1

只有cust_type這個條件,而沒有create_date走不上索引ind_ins_user5_571

?在多表關聯的情況下,即使表很小,在關聯欄位上加索引往往都非常有效,可能影響表的連線方式而節約成本。

?不要試圖每一個欄位上都加索引,索引越多對錶的DML影響越大,對DML要求很高的介面表都不建議加索引,組合索引的列越多,索引樹可能越深,有時候不但不能查詢提速,反而還影響了DML效率。

例如:Where條件中有一個選擇性非常好的欄位,如BILL_ID/ACC_ID/USER_ID,其他選擇條件如STATE/TYPE沒有必要再進行組合索引。

1.4老闆再也不用擔心我的資料積壓啦

某報表庫下有這樣一條sql,每個地市啟動了10個執行緒,去進行資料處理,每個地市執行頻率每小時高達幾萬次,造成資料庫CPU壓力巨大,而降低執行緒又會出現資料積壓,咋整呢?DBA們也捉急呀!

select ROWID, t.*

from CHK_ORD_INTERFACE_574 t

where mod(INTERFACE_ID, :"SYS_B_0") = :"SYS_B_1"

and SCAN_STATE = :"SYS_B_2"

and rownum <= :"SYS_B_3"

sql特點:執行計劃走全表掃描,過濾條件SCAN_STATE欄位只有2鍾情況(0,1是否已稽核)

業務特點:CHK_ORD_INTERFACE_NN表從營業端通過dsg同步到報表端,在報表端進行資料稽核,稽核過的資料進行delete,本表按日進行分割槽,也就是碎片重用率很低,造成本表碎片極為嚴重,碎片率達99%以上,因dsg同步是通過rowid進行,造成本表不能通過move,shrink等手段進行碎片清理。走不上分割槽,過濾條件選擇性低!不能整理碎片!看起來這不是沒辦法嘛?!

方案:本表的碎片率高達99%,說明實際的資料量非常少,可以建立全域性索引(本表的生命週期是永久保留,全域性索引在本業務特點下可以提高索引碎片的重用率,有效控制索引大小),資料塊雖然很多,索引很小呀,建立,有效!原來1.4S,建立索引後0.002s,執行緒調整到1,照樣完成任務,CPU也下去了,老闆再也不用擔心我的資料積壓啦!

02第二劍中衝劍:合理的邏輯

1.1 有效利用連線,避免巢狀

表的外連線一般都會比半連線效率上高的多,在保證業務效果的情況下,我們更建議表關聯代替IN/EXISTS子查詢,好處多多,關係到驅動表啦,連線模式啦,這裡不細表。有興趣,請實踐,有疑問,喊DBA!

在某報表系統的專項優化中,我們抓到了一個異常複雜的sql涉及到13張表,5層的巢狀....通過分析業務需求之後,發現用多表關聯可以代替In字查詢(業務效果不變)我們將SQL裡面的三個小段落做了類似如下修改,並在關聯鍵上建立了索引,由原來跑2個小時提速到10秒之內:

wpsFEAB.tmp

修改為:

wpsFEAC.tmp

1.2 括號內外差別很大

直接上菜:

原sql

wpsFEBC.tmp

wpsFEBD.tmp

問題出在哪裡呢?本sql緩慢的根源是括號,括號犯了什麼罪?他造成了針對RP_BUSI_DETAIL_NNN(571 180G)進行全表掃描,而業務特點是讀取distinct customer_order_id, SALER_ID 且與RPT.INSX_OFFER_PRG_577 的ustomer_order_id列進行關聯。

方案:建立customer_order_id, SALER_ID的組合索引(兩列都非空),並將RPT.INSX_OFFER_PRG_NNN表的其他過濾條件放進子查詢中,這樣sql執行計劃掃描索引,而且不進行回表。

效果:這個sql在1小時快照週期內就沒有完成過,不過優化後就好啦,在不同的條件範圍內1-30秒都可以完成。

新sql:

wpsFECE.tmp

wpsFECF.tmp

1.3 深入理解業務,利用好分割槽

很可惜,上個故事還沒有結束,過了一個星期,業務側反映有些業務很快了,可是有些卻很慢,特別是一次性統計3個月的報表根本就跑不了......有些快?有些慢?這個是重點,立即聯絡業務側和開發確認快和慢的場景,並進行了跟蹤,發現快的場景下都輸入了ORG_ID條件,而慢的場景下都沒有ORG_ID條件,那麼關鍵點就在這裡了!

不帶條件ORG_ID = :ORG_ID,某月份的資料為例,那麼符合條件的INSX_OFFER_PRG_571的資料有14萬之多,與RP_BUSI_DETAIL_NNN表關聯時 CBO優化器只會選擇hash jion連線,且選擇的索引只能是done_date(取出範圍內的資料後再進行hash),如此大的兩張表肯定沒法在50秒內(超時限制)完成,而輸入了條件IOP.ORG_ID = :ORG_ID那麼符合條件的INSX_OFFER_PRG_571的資料在100條以內,sql可以走巢狀迴圈,而且兩張表都可以利用到高效的索引,速度自然就大大提高。

那麼不帶條件ORG_ID = :ORG_ID下能不能快呢?最後發現了一個關鍵點RP_BUSI_DETAIL_NNN是個按月分割槽表,每個分割槽只有1-6G,比起180G自然是小的多了!而且分割槽欄位也是DONE_DATE,很可惜sql中沒有利用到分割槽,立即聯絡需求側和開發側確認,INSX_OFFER_PRG_NNN 和RP_BUSI_DETAIL_NNN兩張表的DONE_DATE在業務意義上是否一致或者差距很小?是否可以把RP_BUSI_DETAIL_NNN表的DONE_DATE也一併放在條件中?非常幸運,我的這個提議立刻得到了肯定的回覆,在後續的溝通和測試下,重新定製了業務規則,最多隻能按自然月查詢(考慮表按自然月分割槽)查詢,業務超時由原來的50秒改成3分鐘,最終將SQL改寫成了:

wpsFEE0.tmp

wpsFEE1.tmp

雖然目前的執行計劃中INSX_OFFER_PRG_NNN 和RP_BUSI_DETAIL_NNN兩張表還是通過hash jion連線,資料量也還是較大,但是我們走上了分割槽過濾,特別是RP_BUSI_DETAIL_NNN這張大表只會單分割槽掃描,所以在新的規則和超時機制下我們順利的完成了這個報表的優化。

1.4 資料庫遷移前的優化

背景:某個有點年頭的資料庫在某次專案改造中需要遷移並升級到新的機器上,這個庫因為業務不停的上線和實在有點低的硬體配置原因在遷移升級前主機CPU的使用率也是很高了,而遷移需要藉助某第三方工具,這個工具的初始化過程需要有足夠的CPU資源,而割接時間視窗和業務原因只能準線上割接(可以停業務的時間很短),也就是說雖然這個資料庫在目前的低配置機器上轉不了幾天了,但是為了保證割接的順利進行DBA們還是硬著頭皮去進行優化。

優化過程中的一個案例:

原sql:

wpsFEE2.tmp

wpsFEF2.tmp

wpsFEF3.tmp

wpsFF04.tmp

這個SQL執行時間在25秒左右,邏輯上看起來實在是有點複雜,不過我們耐心的拆解分析下找到了第一個突破點:修改以下子查詢的寫法

wpsFF05.tmp

上面的寫法等同於:

下面的寫法執行時間可以從15秒降到10秒,有些進展!繼續。

考慮到這個子查詢所進行的表連線,可以將連線條件放置在這個子查詢的where字句中,進一步簡化邏輯,改寫為:

wpsFF16.tmp

wpsFF17.tmp

該子查詢的執行時間進一步減少到1.7秒,在原SQL中使用這個新子查詢,原SQL的執行時間從25秒減少到4.6秒,效能提高了5倍多。好了,理解聯絡開發進行測試驗證,2天后他們反饋業務效果完全一樣,而且速度的確明顯快了很多!

看吧!我們什麼也沒做,沒有加索引,沒有改造表的物理模型,僅僅通過梳理邏輯,簡化sql執行的步驟和避免重複資料掃描就完成了一項優化,所以我們以後在寫程式碼的過程中是不是要多想一想呢?!通過2周的努力,我們終於將主機CPU使用率給總體降下來接近10%,順利的保障了割接。

03三劍連出1.關衝劍:繫結執行計劃

1.1 合理利用Hints

Hints定製執行計劃,在割接、經分、稽核等場景下應用廣泛,合理的利用可以有效利用資源,提高執行效率。

Parallel 並行:合理的利用parallel可以有效利用資源,提高執行效率。但是在日常生產期間,核心庫不允許吆!Parallel開的越高,就是並行度越高,那麼資源使用就越嚴重,所以既要考慮效率,也要考慮負載,曾經在某些系統中抓到了/*+parallel(a,64)*/,這位老兄!我們邏輯的CPU也不過只有32顆!

Select /*+parallel(a,6)*/count(*) from ins_offer_571 a where .....

Append nologging:Append nologging 高水位直接路徑寫入,減少寫日誌,經分,割接場景下較多使用

INSERT /*+ APPEND NOLOGGING PARALLEL(TMP_H_MD_PAR_EXT_USER_D16,3) */

INTO TMP_H_MD_PAR_EXT_USER_D16

(......)

SELECT /*+PARALLEL(R,3)*/*

from H_MD_BLL_TMN_BUSN_D_574 PARTITION(P20150406) R

/*+index(a,index_name)*/ 指定索引掃描

/*+full(a)*/ 指定全表掃描

........ 還有好多,這裡不一一列舉了,都在:select * from v$sql_hint

1.2 SQL PROFILE,還好有你!

某報表庫有個前臺的多選框操作的報表,sql的條件組合多樣化,表RP_BUSI_DETAIL_NNN上存在12個索引,且多為組合索引,索引鍵重複情況較多,某天爆發了一下,大量的執行計劃走錯,統計資訊收集了,遊標刷出去了,沒有效果。大白天的改造索引風險又太高,還好本sql有個特點,DONE_DATE欄位一定要用的...... 情況緊急!DBA們還有一招 SQL PROFILE。

wpsFF18.tmp

1 獲取outline

select* fromtable(dbms_xplan.display_cursor('0bbt69m5yhf3p',null,'outline'));

2 建立sql profile 繫結執行計劃

wpsFF28.tmp

wpsFF29.tmp

繫結完成後,kill執行計劃有問題的SQL,資料庫的效能就逐漸恢復了。後續業務梳理完成後改造了索引,各類sql的執行計劃也就都穩定了。

2.少衝劍:怎麼就突然慢了?緣來是你!

某核心系統的維護找過來,天天跑的一個作業這幾天變慢了,原來跑1.5-2個小時的作業,現在6個小時了也沒跑出來。老闆說搞定他!

Sql過來了:

wpsFF3A.tmp

執行計劃先看看

wpsFF3B.tmp

這不是在動態取樣嘛!還是level=7的,難不成跑了6個小時還是在動態取樣中?開個10046看看會話在什麼,一看不僅僅有動態取樣造成的問題呀,還有GC!

wpsFF4B.tmp

趕緊回訪一下,果然這個作業一直就是跑在1號節點的。DR_GGPRS_XX_YYYYMMDD 是在2號節點入庫的!那麼在1號節點執行本作業就是有問題!

動態取樣怎麼辦呢?這個DR_GGPRS_XX_YYYYMMDD表大地市超過400G,想收集統計資訊是不可能的,何況作業每天僅僅跑一次,也不存在什麼遊標共享的問題了,乾脆直接繫結執行計劃,避免動態取樣,在2號節點測試一下。

wpsFF4C.tmp

1590s完成!

通知應用,本作業調整到2號節點,並通過Hints /*+parallel(a,4) dynamic_sampling(a,0)*/

避免動態取樣,後續反饋作業都可以在30分鐘內完成。

3.少澤劍:高效的update,不能為所欲為!

某核心系統,Cpu使用率接近100%,監聽的響應速度非常慢,主營業務資料入庫積壓嚴重!分析過後找到了罪魁禍首,竟然是幾個迴圈的update語句把CPU耗盡的!

我們來看看他的威力:

wpsFF4D.tmp

僅僅從語句的變數中就發現了一個問題:本語句是迴圈執行的!而且迴圈次數非常多!找到應用方,電話回訪,果然如此!而且本作業跑了一天了好沒有跑完。

匹配條件表DR_GGPRS_XX_YYYYMMDD根據地市不同在70-200G之間,資料量都是億級,執行計劃都不用看了,有沒有索引都不重要了,就憑著這麼迴圈下去,我也只能呵呵了!

被更新的表user_fenleijx_temp_YYYYMMDD很小啊,才幾百MB!我前面說什麼來著?!一個SQL能不能本質上被提速,看看他最終業務上需要掃描的資料就可以了,這必須可以提速啊!

我們開始吧!

1.create tmp_table

create table jf.tmp_tab1 parallel 10 nologging as select distinct user_number from jf.dr_ggprs_jx_20150203 where charging_characteristics='04';

create table jf.tmp_tab2 parallel 10 nologging as select distinct user_number from jf.dr_ggprs_jx_20150203 where charging_characteristics='0400';

2.Create unique index

create unique index jf.ind_user_number_1 on jf.tmp_tab1(user_number) nologging;

create unique index jf.ind_user_number_2 on jf.tmp_tab2(user_number) nologging;

3.高效的update

update (select a.status

from bossmdy.user_fenleijx_temp_20150203 a,

jf.tmp_tab1 b

where a.user_number = b.user_number

and a.status = '3')

set status = '0';

update (select a.status

from bossmdy.user_fenleijx_temp_20150203 a,

jf.tmp_tab2 b

where a.user_number = b.user_number

and a.status = '3')

set status = '0';

不需要迴圈update,只需要建立一張匹配條件為唯一性的臨時表,再建立一個唯一性索引,一次性update目標表,整個工作耗時10分鐘。不僅僅是高效,CPU資源的高消耗也沒有了,資料庫恢復了正常。

高效UPDATE方式

update (select a.col_a,b.col_b from t_tab_a a,t_tab_b b where a.id=b.id and b.col_x=’x’) c

set c.col_a=c.col_b;

要保證匹配條件b.id上有唯一性索引,如果沒有唯一性索引則可以通過建立中間表的方式取出唯一性資料再建立唯一性索引如:

Create table t_tab_c as select * from t_tab_b where b.col_x=’x’;

Create unique index ind_t_tab_c on t_tab_c(id);

04第六劍1.商陽劍:割接這三板斧!

說起割接,是讓DBA、開發、測試等人都談虎色變的事情,因為割接時間視窗緊張,割接資源消耗嚴重,割接要各種備份,割接產生大量日誌,跑錯了要回滾........總之風險有點高。

1.1 備份、臨時表不寫日誌

割接中需要大量的備份、拍照,減少寫日誌可以有效提高效率,也能減輕資料庫的歸檔壓力,因為我們很多庫上還有DSG同步,減少日誌量也能避免DSG分析延遲。

wpsFF5E.tmp

3.ddl 代替 dml,減輕undo壓力

將A表的資料全部插入到新建的B表,推薦的做法:

create table B tablespace tbs_data nologging as select * from B;

rename 和 CTAS (create table as select)建表是在割接場景中很受歡迎的做法

1.2 批量提交,降低UNDO/REDO壓力

割接的時候有很多場景需要對大表進行DML,一次性執行大表的DML一般效率較低,而且undo表空間壓力很大,一旦取消,大事物回滾非常消耗效能,可能會影響後續割接,而用遊標進行一條條的提交,同樣會造成redo的IO問題,也可能造成大量的log file sync事件。因此對大表進行全量或者是近全量DML時我們建議採用批量提交。

wpsFF5F.tmp

1.3 提高聚簇因子,只爭朝夕!

wpsFF70.tmp

在某個每月一次的維護作業下有如上一段指令碼,本質上就是對大表I_USER_STATUS_CENTER進行按條件的批量更新,表I_USER_STATUS_CENTER上有約16億資料,且MSISDN列上有索引,distinct number約1.1萬所有,也就是每次迴圈符合條件的資料:16億/1.1萬=15萬。

都按照步驟做了,可是跑了2個小時也沒有跑完........

執行計劃也看過了,走索引,沒問題!表的屬性暫時改成nologging了,不寫日誌了!夠了吧?!可是速度還是不行,一分析,預計72小時以上.........在核心庫上執行這樣的作業哪裡可以忍受?!該做的都做了,難道沒辦法再提速了麼?

前面有個例子,操場上撿玻璃球,現在不是一個一個的撿,而是一組一組的撿,每組按照顏色不同來撿,一次撿1.5萬,如果這每組球都分散在不同的地方,有了索引又如何呢,撿這麼多還不是累死人?!如果說每組的球都堆在一個地方,不是分散到各個角落,那麼是不是會快許多呢?!

這就是提高聚簇因子。

(1)將目標表按照MSISDN排序重建。

Alter table I_USER_STATUS_CENTER rename to I_USER_STATUS_CENTER_bak;

Create table I_USER_STATUS_CENTER tablespace tbs_data parallel 10 nologging as

Select /*+parallel(a,10)*/* from I_USER_STATUS_CENTER_bak a order by MSISDN;

Create index ind_ USER_STATUS_CENTER1 on I_USER_STATUS_CENTER(MSISDN) tablespace tbs_data parallel 10 nologging;

Alter table I_USER_STATUS_CENTER noparallel;

Alter index ind_ USER_STATUS_CENTER1 noparallel;

(2)MSISDN列上建立索引

(3)執行上面的指令碼1.5小時完成

(4)修改表和索引的日誌屬性

Alter table I_USER_STATUS_CENTER logging;

Alter index ind_ USER_STATUS_CENTER1 logging;

(5)還可以更快麼?

可以的!可以將遊標按照業務欄位net_id進行範圍拆分,如:

SELECT NET_ID||HLR_SEGMENT BILL_ID,REGION_ID FROM RES_NUMBER_HLR where net_id >=1 and net_id<100;

SELECT NET_ID||HLR_SEGMENT BILL_ID,REGION_ID FROM RES_NUMBER_HLR where net_id >=100 and net_id<200;

........

拆分成8個遊標,同時將這段程式放在不同的視窗執行,那麼15分鐘之內我們這個作業就會完成啦!

2.總結

本期的漫談SQL優化就暫時講到這裡了,這裡通過幾個例子希望能給大家一點啟發。在SQL優化過程中往往都不是那麼順利的,大部分情況下都是跟系統問題、業務需求、物理模型等緊密相連的,需要分析考慮的地方很多。兵無常勢,水無常形。我們這裡也沒有萬能公式,不過我們IT人有認真負責、靈活運用、鑽研到底的態度,所以很多難題我們最終都能迎刃而解!

About Me

....................................................................................................................................................

本文來自於微信公眾號轉載文章,若有侵權,請聯絡小麥苗及時刪除

ITPUB BLOG:http://blog.itpub.net/26736162

QQ:642808185 若加QQ請註明您所正在讀的文章標題

【版權所有,文章允許轉載,但須以連結方式註明源地址,否則追究法律責任】

....................................................................................................................................................

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/26736162/viewspace-2080717/,如需轉載,請註明出處,否則將追究法律責任。

相關文章