數據庫訪問性能優化(四)

4.2、合理使用排序

Oracle的排序算法一直在優化,可是整體時間複雜度約等於nLog(n)。普通OLTP系統排序操做通常都是在內存裏進行的,對於數據庫來講是一種CPU的消耗,曾在PC機作過測試,單核普通CPU1秒鐘能夠完成100萬條記錄的全內存排序操做,因此說因爲如今CPU的性能加強,對於普通的幾十條或上百條記錄排序對系統的影響也不會很大。可是當你的記錄集增長到上萬條以上時,你須要注意是否必定要這麼作了,大記錄集排序不只增長了CPU開銷,並且可能會因爲內存不足發生硬盤排序的現象,當發生硬盤排序時性能會急劇降低,這種需求須要與DBA溝通再決定,取決於你的需求和數據,因此只有你本身最清楚,而不要被別人說排序很慢就嚇倒。算法

如下列出了可能會發生排序操做的SQL語法:數據庫

Order by緩存

Group by性能優化

Distinct服務器

Exists子查詢網絡

Not Exists子查詢架構

In子查詢併發

Not In子查詢ide

Union(並集),Union All也是一種並集操做,可是不會發生排序,若是你確認兩個數據集不須要執行去除重複數據操做,那請使用Union All 代替Union函數

Minus(差集)

Intersect(交集)

Create Index

Merge Join,這是一種兩個錶鏈接的內部算法,執行時會把兩個表先排序好再鏈接,應用於兩個大表鏈接的操做。若是你的兩個錶鏈接的條件都是等值運算,那能夠採用Hash Join來提升性能,由於Hash Join使用Hash 運算來代替排序的操做。具體原理及設置參考SQL執行計劃優化專題。

 

4.3、減小比較操做

咱們SQL的業務邏輯常常會包含一些比較操做,如a=ba之類的操做,對於這些比較操做數據庫都體現得很好,可是若是有如下操做,咱們須要保持警戒:

Like模糊查詢,以下所示:

a like ‘c%’

 

Like模糊查詢對於數據庫來講不是很擅長,特別是你須要模糊檢查的記錄有上萬條以上時,性能比較糟糕,這種狀況通常能夠採用專用Search或者採用全文索引方案來提升性能。

不能使用索引定位的大量In List,以下所示:

a in (:1,:2,:3,…,:n)   ----n>20

若是這裏的a字段不能經過索引比較,那數據庫會將字段與in裏面的每一個值都進行比較運算,若是記錄數有上萬以上,會明顯感受到SQLCPU開銷加大,這個狀況有兩種解決方式:

a、  in列表裏面的數據放入一張中間小表,採用兩個表Hash Join關聯的方式處理;

b、  採用str2varList方法將字段串列表轉換一個臨時表處理,關於str2varList方法能夠在網上直接查詢,這裏不詳細介紹。

 

以上兩種解決方案都須要與中間表Hash Join的方式才能提升性能,若是採用了Nested Loop的鏈接方式性能會更差。

若是發現咱們的系統IO沒問題可是CPU負載很高,就有多是上面的緣由,這種狀況不太常見,若是遇到了最好能和DBA溝通並確認準確的緣由。

 

4.4、大量複雜運算在客戶端處理

什麼是複雜運算,通常我認爲是一秒鐘CPU只能作10萬次之內的運算。如含小數的對數及指數運算、三角函數、3DESBASE64數據加密算法等等。

若是有大量這類函數運算,儘可能放在客戶端處理,通常CPU每秒中也只能處理1-10萬次這樣的函數運算,放在數據庫內不利於高併發處理。

 

5、利用更多的資源

5.1、客戶端多進程並行訪問

多進程並行訪問是指在客戶端建立多個進程(線程),每一個進程創建一個與數據庫的鏈接,而後同時向數據庫提交訪問請求。當數據庫主機資源有空閒時,咱們能夠採用客戶端多進程並行訪問的方法來提升性能。若是數據庫主機已經很忙時,採用多進程並行訪問性能不會提升,反而可能會更慢。因此使用這種方式最好與DBA或系統管理員進行溝通後再決定是否採用。

 

例如:

咱們有10000個產品ID,如今須要根據ID取出產品的詳細信息,若是單線程訪問,按每一個IO5ms計算,忽略主機CPU運算及網絡傳輸時間,咱們須要50s才能完成任務。若是採用5個並行訪問,每一個進程訪問2000ID,那麼10s就有可能完成任務。

那是否是並行數越多越好呢,開1000個並行是否只要50ms就搞定,答案確定是否認的,當並行數超過服務器主機資源的上限時性能就不會再提升,若是再增長反而會增長主機的進程間調度成本和進程衝突機率。

 

如下是一些如何設置並行數的基本建議:

若是瓶頸在服務器主機,可是主機還有空閒資源,那麼最大並行數取主機CPU核數和主機提供數據服務的磁盤數兩個參數中的最小值,同時要保證主機有資源作其它任務。

若是瓶頸在客戶端處理,可是客戶端還有空閒資源,那建議不要增長SQL的並行,而是用一個進程取回數據後在客戶端起多個進程處理便可,進程數根據客戶端CPU核數計算。

若是瓶頸在客戶端網絡,那建議作數據壓縮或者增長多個客戶端,採用map reduce的架構處理。

若是瓶頸在服務器網絡,那須要增長服務器的網絡帶寬或者在服務端將數據壓縮後再處理了。

 

5.2、數據庫並行處理

數據庫並行處理是指客戶端一條SQL的請求,數據庫內部自動分解成多個進程並行處理,以下圖所示:

 

數據庫訪問性能優化(四) 

並非全部的SQL均可以使用並行處理,通常只有對錶或索引進行所有訪問時纔可使用並行。數據庫表默認是不打開並行訪問,因此須要指定SQL並行的提示,以下所示:

select  * from employee;

 

並行的優勢:

使用多進程處理,充分利用數據庫主機資源(CPU,IO),提升性能。

並行的缺點:

1、單個會話佔用大量資源,影響其它會話,因此只適合在主機負載低時期使用;

2、只能採用直接IO訪問,不能利用緩存數據,因此執行前會觸發將髒緩存數據寫入磁盤操做。

 

注:

1、並行處理在OLTP類系統中慎用,使用不當會致使一個會話把主機資源所有佔用,而正常事務得不到及時響應,因此通常只是用於數據倉庫平臺。

2、通常對於百萬級記錄如下的小表採用並行訪問性能並不能提升,反而可能會讓性能更差。

相關文章
相關標籤/搜索