資料庫(五)資料庫訪問效能優化

2021-07-10 19:57:31 字數 2801 閱讀 6227

乙個優良的系統,效能問題是我們必須考慮的問題,而資料庫的效能瓶頸也是我們不得不面對的問題,本章我們將**一下關於資料庫訪問效能優化方面的問題。

.1)資料庫訪問涉及到的層面

cpu及記憶體:快取資料訪問、比較、排序、事務檢測、sql解析、函式或邏輯運算。

網            絡:結果資料傳輸、sql請求、遠端資料庫訪問(dblink)。

硬            盤:資料訪問、資料寫入、日誌記錄、大資料量排序、大表連線。

.2)資料庫優化基本法則

這個優化歸納為5個層次:

(a) 減少資料訪問(減少磁碟訪問)

(b)返回更少資料(減少網路傳輸或磁碟訪問)

(c) 減少互動次數(減少網路傳輸)

(d)減少伺服器cpu開銷(減少cpu及記憶體開銷)

(e)利用更多資源(增加資源)

下面我們針對上面的優化法則一一說明。

(a)減少資料庫訪問

減少資料庫訪問,簡而言之,就是儘量減少系統與資料庫的互動,因為對資料庫的訪問必然存在效能的消耗,我們可以從以下幾個方面來思考。

(a.1)使用資料庫索引

關於資料庫索引的使用,請參考 資料庫(六)資料庫索引

(a.2)優化sql執行計畫

sql執行計畫是關係型資料庫最核心的技術之一,它表示sql執行時的資料訪問演算法。優秀的關係型資料庫除了需要支援複雜的sql語法及更多函式外,還需要有一套優秀的演算法庫來提高sql效能。由於sql執行計畫是乙個比較專業的話題,本章節就不多加敘說,後續有計畫再討論

(b) 返回更少的資料

(b.1)資料分頁處理

對需要獲取的資料,進行分頁處理,避免一次獲取資料量過大,請參考:資料庫(七)資料庫分頁處理

(b.2)只返回需要的字段

查詢資料庫表資料時,返回必須的字段,避免採用select * 模式。

(c)減少互動次數

(c.1)採用批處理

資料庫訪問框架一般都提供了批量提交的介面,jdbc支援batch的提交處理方法,當你一次性要往乙個表中插入1000萬條資料時,如果採用普通的executeupdate處理,那麼和伺服器互動次數為1000萬次,按每秒鐘可以向資料庫伺服器提交10000次估算,要完成所有工作需要1000秒。如果採用批量提交模式,1000條提交一次,那麼和伺服器互動次數為1萬次,互動次數大大減少。採用batch操作一般不會減少很多資料庫伺服器的物理io,但是會大大減少客戶端與服務端的互動次數,從而減少了多次發起的網路延時開銷,同時也會降低資料庫的cpu開銷。

(c.2)in查詢

資料庫查詢中,有時候會遇見多個字段查詢,這時建議採用in(id1,id2,id3),採用這種方式可以減少sql請求次數,以提高效能。但是需要注意的時,採用in查詢時,id的數量會有限制(各個資料庫都會有sql長度及in個數的限制),當id個數過多時,採用in查詢,效能基本上沒有什麼提高,比如說,如果id的個數達到1000以上,這時就建議採用全表查詢了,因為隨著sql中in的裡面的值個數增加,sql的執行計畫會更複雜,占用的記憶體將會變大,這將會增加伺服器cpu及記憶體成本。

(c.3)設定fetch size

當我們採用select從資料庫查詢資料時,資料預設並不是一條一條返回給客戶端的,也不是一次全部返回客戶端的,而是根據客戶端fetch_size引數處理,每次只返回fetch_size條記錄,當客戶端游標遍歷到尾部時再從服務端取資料,直到最後全部傳送完成。所以如果我們要從服務端一次取大量資料時,可以加大fetch_size,這樣可以減少結果資料傳輸的互動次數及伺服器資料準備時間,提高效能。

(c.4)使用儲存過程、檢視、函式

前面我們討論過分頁處理,其實在資料庫中還有一種方式處理返回結果,那就是resultset游標,後續詳細討論資料庫游標相關知識。

(d)減少伺服器cpu開銷(減少cpu及記憶體開銷)

(d.1)使用繫結變數

在解釋使用繫結變數之前,我們先來看看sql執行原理,一條sql在oracle資料庫中的執行過程如下圖所示:

(1)當一條sql傳送給資料庫伺服器後,系統首先會將sql字串進行hash運算,得到hash值後再從伺服器記憶體裡的sql快取區中進行檢索,如果有相同的sql字元,並且確認是同一邏輯的sql語句,則從共享池快取中取出sql對應的執行計畫,根據執行計畫讀取資料並返回結果給客戶端。

(2)如果在共享池中未發現相同的sql則根據sql邏輯生成一條新的執行計畫並儲存在sql快取區中,然後根據執行計畫讀取資料並返回結果給客戶端。

為了更快的檢索sql是否在快取區中,首先進行的是sql字串hash值對比,如果未找到則認為沒有快取,如果存在再進行下一步的準確對比,所以要命中sql快取區應保證sql字元是完全一致,中間有大小寫或空格都會認為是不同的sql。如果我們不採用繫結變數,採用字串拼接的模式生成sql,那麼每條sql都會產生執行計畫,這樣會導致共享池耗盡,快取命中率也很低。

知道了sql執行原理,我們再看繫結變數,繫結變數是指sql中對變化的值採用變數引數的形式提交,而不是在sql中直接拼寫對應的值。

非繫結變數寫法:select * from employee where id=1

繫結變數寫法:

select * from employee where id=?

preparestatement.setint(1,1)

(e)利用更多資源(增加資源)

增加資源來提高資料庫效能,可以從多個方面考慮,比如採用負載均衡、資料庫分庫分表,採用資料庫**及通過讀寫分離等,這些會在資料庫章節一一介紹。

參考:

Django 資料庫訪問效能優化

1.使用標準的資料庫優化技術 在進行django資料庫訪問效能優化之前,首先應該使用標準的資料庫技術對其進行優化,比如給字段加索引,通過使用 django.db.models.field.db index 來給乙個django模型類的字段加索引,設定這個屬性欄位的field.db index tru...

Mysql資料庫訪問效能優化

如何在mysql中分配innodb buffer pool size 節選部分 緩衝池大小必須始終等於或者是innodb buffer pool chunk size innodb buffer pool instances的倍數。如果將緩衝池大小更改為不等於或等於innodb buffer poo...

Oracle資料庫訪問效能優化

最近在做有關查詢資料庫的工作,由於乙個表的資料量過大,導致程式程序卡死情況出現,sql優化迫在眉睫,索引閃亮登場!oracle中查詢走索引的情況 1 對返回的行無任何限定條件,即沒有where子句。2 未對資料表與任何索引主列相對應的行限定條件。例如 在id name time列建立了三列復合索引,...