給PLSQL插上飛翔的翅膀-PLSQL優化

60-80% of database performance issues are related to poorly performing SQL,60-80%的數據庫性能問題要歸結於生產中糟糕的SQL語句!


以此一文來總結筆者近10多年來的工作經驗並基於最基本的也是最有效的對於Oracle數據庫中的RBO、CBO、索引、WHERE條件進行講解同時配以大量案例來幫助讀者從此文中學到的相關的理論知識快速的運用到其正在從事的生產環境中的優化過程中去。

優化的理論基礎



通過Select Count(?)進入優化之旅


不看百度或者GOOGLE說出下面3者的區別?


SELECT COUNT (*)


SELECT COUNT(1)


SELECT COUNT(字段名)


SELECT Count(?)的知識



ORACLE的優化器


要說PLSQL優化,我們先需要來好好說一下Oracle優化器的知識:



優化器的優化模式



CBO模式



RBO模式



一起來看看oracle優化器的發展歷程



所以,我們知道ORACLE10後開始默認使用CBO,在CBO時ORACLE會自動來選擇最優的執行計劃,有時我們會認爲:這個應該走索引更好啊,但是對於CBO來說,一個FULL TABLE ACCESS反而比索引更有效。


因此,在CBO的模式下,我們需要做的就是:


  1. 做好數據庫信息的相關統計
  2. 合理建設我們的索引
  3. 優化我們的SQL

讓我們從索引的基本知識下手吧


索引是不需要修改SQL最直接帶來性能提升的利器,何時該建索引,怎麼建?怎麼樣讓你的索引更合理?

索引按內部結構分類



索引按功能分類




索引按索引對象分類



建立索引的方法論

上面介紹了這麼多索引的分類,下面來講講建立索引的方法論吧,大家可能較關心這個,因爲這個是經驗總結也是實戰有用的利器哈。





不建議建立索引的情況


索引很神奇,可是索引不是萬能,有時你建了索引也等於沒用或者是白建、作無用功,爲什麼呢?我們看下去。





索引不會生效的情況

所以索引不要亂建,有時建了也是白建,爲什麼呢?來看看下面的案例分析吧:




以案例來說明


PLSQL優化>一個不走索引的優化案例



這個例子說明了,如果你有一字參於WHERE條件查詢的字段,但是它參於了運算符,因此它在ORACLE的內部執行計劃中是不會走索引的,因此我們做了一個小小的變化,效率提升了多少倍?5.3倍,530%,呵呵!


以上例我們可以爲建立索引作一個總結。


建立索引的總結





Table Analyze



Analyze Table VS DBMS_STATS



Import & Export


說到Import & Export命令,大家會說。。。哎,這個不是很簡單,就是:imp username/pwd@oraid file=path 嗎?嘿嘿。。。試想:


  1. 你需要導入一個8GB左右的.dmp文件進入數據庫
  2. 你需要將一個庫,其中含有至少30張表並且每張表都超過1200萬條記錄的數據進入一個.dmp文件
然後你去試試看這個耗時。


Import的常規做法


這是一個真實的案例,我們在CCC即世界著名車險公司項目中,我們定期會和CCC芝加哥總部同步一個8GB左右的.dmp文件進入我們的數據庫,由於安全原因因此需要依靠.dmp交換文件的形式於零晨同步至中國的數據庫,並且在T+1第二天早晨的8:00前完成同步。

於是,我們的DBA開始來了。。。。。。


從零晨到第二天早上8:00,硬是沒有導完,一查,數據庫中session已經超時了,連續2天還是這樣。

於是,我們把原有的語句稍稍作了一下變化:

只是把原來的一句imp折成了2條:

  • 第一條,只導數據,不導索引,並且設置成10000條數據一次commit,同時設置了一個緩衝池
  • 第二條,只導索引,不導數據,並且設置成10000條數據一次commit,同時設置了一個緩衝池

結果讓人驚歎。。。發覺最後只用了40分鐘不到,兩條語句全部執行完畢,完成了導入。。。其實這個原因我可以用下面2個例子來說明:

  1. 一個含有8GB文件內容的目錄,用FTP客戶端下載,你會發覺似乎永遠等不到頭,幾小時就這樣耗着,然後你改成先把這個目錄打成一個壓縮包,然後再用FTP客戶端 下載,幾十分鐘就能搞定。
  2. 你用JDBC寫一個FOR循環插入100萬條記錄。。。結果是ORACLE直接爆掉,而你採用批量提交。。。結果是驚人的!
其實我們當時所做的折分,原理如同上述兩個案例,是一樣的道理,減少IO讀寫,設置緩衝,批量提交。如果你的事務太大。。。。。。


以案例來說明PLSQL的優化


PLSQL優化-SELECT IN 與SELECT EXISTS




這邊提高了多少?光看IO就知道提高了多少了,呵 呵,很好玩吧?再來!

PLSQL優化-SELECT IN的幾種優化




PLSQL優化-SELECT IN、OR、UNION的互轉



看看3次修改,最後一次,提升了多少倍?11.2850-0.0261再除以0.0261=431.375,431.375倍。。。。。。一條SQL啊。。。在寸土寸金的互聯網應用中,單條SQL提高了431.375倍。。。這是什麼概念!!!

你好討厭!!!再來!!!


PLSQL優化-分頁語句中加入索引的優化


以下是一條分頁語句,我們對created_date做一個索引,等。。。。。。等等等,這邊的索引不是一般的索引,我們把圖形化工具建的索引翻譯成SQL:

create index IDX_WAREHOUSE_CT on T_WAREHOUSE(CREATED_DATE DESC);


我們這個表是一個含有1000萬條記錄的表,僅此一招,整個SQL查詢提高了300%-340%



PLSQL優化-INNER JOIN VS WHERE





PLSQL優化-WHERE語句優化要點


注意下面這個例子,只是WHERE條件後的順序上下顛倒一下,就提高了10倍的效率,呵呵。



WHERE語句中選擇最有效的表名順序





好玩吧!!!再來!!!





PLSQL優化-用UNION取代OR

看看下面這個例子吧:



是不是寫SQL時稍微注意一下。。。這個效率。。。這個性能 。。。123%。。。123%的提高啊。

PLSQL優化>共享SQL


前面我們用好幾個實例說了一下PLSQL中最基本的一些性能上可以帶來的提升,這邊我們需要提一下ORACLE自帶的一個緩衝SQL結果集命中率的工具




所以,我們在寫SQL時要用JAVA的PreparedStatement,要用:1這樣的東西來做傳值,因爲ORACLE是自帶SQL緩衝池的,另外在此要多說一句的是,雖然ORACLE10後開始帶有ASM(自動內存管理),但有時ASM不是萬能,對於一些大形網站,有時我們的DBA是需要手工去調整ORACLE的SGA,即:



因此,這對我們的ORACLE DBA來說提出了更高的要求。

PLSQL優化的基礎掌握了上述幾點,基本可以讓你的系統性能提高2位數-3位數,後續感興趣的讀者還可以繼續去看:




如何自學


對於ORACLE的PLSQL相關調優該如何自學呢?




是不是很自虐哈。。。

那我們就用著名的Opensource界的一句銘言:play by yourself, play with it。

用中文來說那就是:自虐着並快活着

要成爲“東方不敗。。。”-- 蒼海。。。笑。。。濤濤兩岸潮。。。呵呵。







筆者聯繫方式:

QQ:42948648

微信:


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章