Postgresql的CURSOR SHARING

DBAIOps社群發表於2024-02-20

Oracle DBA 最怕遇到 C URSOR 相關的問題,如果發生了 C URSOR 爭用導致的效能問題,是很難在短時間內分析清楚的。有時候我們重啟資料庫就解決了這個問題,不過有時候重啟資料庫後問題依然存在。幸運的是在 PostgreSQL資料庫中好像很少會遇到類似的問題,這是什麼原因呢?

在一個高併發的系統中, S QL 執行過程需要對 S QL 進行編譯,這個過程無論哪種資料庫都是必須有的。大體上分為語法語義解析、 SQL REWRITE 最佳化、執行計劃生成、執行計劃選擇、執行等過程。在 PostgreSQL中,可以用下面這個圖來表示。

 

為了避免每次 S QL 執行之前都做上述昂貴的操作, Oracle構建了全域性共享的C URSOR 結構,用於在共享記憶體( S HARED POOL )中儲存 C URSOR 共享部分的資料,用於所有的會話共享。似乎現在的 Mysql、PostgreSQL等開源資料庫和一些國產資料庫都沒有再採用這種全域性共享C URSOR 的機制,而大多數採用 S QL 不共享或者會話內共享 C URSOR 的機制,比如比較新版本的 PostgreS QL 就是採用會話內共享 S QL 的機制。

為什麼 Oracle使用全域性C URSOR 共享機制而 PostgreSQL不使用呢?這實際上有兩方面的原因,一個是歷史原因,一個是商業原因。 CURSOR 共享在 C PU 資源不是很充裕的時代是相當有效提升 R DBMS 執行效率的手段,因為 S QL 解析是十分高開銷的工作,能夠一次編譯多次執行,可以大大提高系統的併發執行效能。因此作為商用資料庫的 Oracle一直把提升C URSOR 共享能力作為其核心競爭力, O RACLE C URSOR 全域性共享就做成了一個獨步天下的技術了。 Postgresql這樣的開源資料庫沒有Oracle的大手筆,因此選擇了較為穩妥的會話內共享S QL 的技術路線。幸虧是現在 X 86 伺服器技術的高速發展, C PU 資源已經不是很難買到的了,因此不能在全域性共享 C URSOR 的問題也已經不是一個特別嚴重的問題了。實際上,這些年我們遇到的因為 C USOR 硬解析導致的 O RACLE 資料庫效能問題也少了很多,主要原因是哪怕 C URSOR 解析使用了 10+%的C PU 資源,對我們的伺服器來說也還是撐得住的。

雖然說 P G 並沒有採用全域性共享 C URSOR 的策略,不過在會話內共享多次執行的 C URSOR 仍然對 P G 資料庫併發執行效能的提升有極大幫助的。說起共享 CURSOR 就不可避免地會聊到繫結變數的使用問題。使用繫結變數的好處是讓 SQL 可以共享,可以讓一條類似的 S QL 在多次執行中 共享查詢執行計劃,這樣就不需要每次都編譯 SQL語句 ;不過使用繫結變了也有缺點,在 Oracle存在的b ind peeking 問題在任何資料庫中都會存在,因為繫結變數的差異可能選擇不同執行計劃才好的問題在很多時候都是存在的。在 Oracle   9 iR2 之前,所有執行計劃都是在變數繫結之前完成的,從 9.2開始, Oracle 將執行計劃的生成放到了變數繫結之後,這樣就讓執行計劃的生成更為精準了,不過這也帶來了另外一個問題,那就是 S QL 第一次執行時的變數成為生成執行計劃的依據,因此 C URSOR 共享會導致存在多種最優執行計劃的 S QL 語句的執行效能變得不穩定。 Oracle   11 g 之後的自適應 CURSOR 共享才基本上解決了這個問題。

PostgreSQL資料庫的C URSOR 共享機制學習了 Oracle的這一個新的特性,採用了一種類似的方法來解決這個即共享C URSOR 又儘可能避免多種最優執行計劃導致的 S QL 效能問題,當然前提是, PostgreSQL的C URSOR 共享是會話級的,不是例項級的。

PostgreSQL的一個會話中,一條S QL 的前五次執行,每次都會重新生成執行計劃,這樣就可以避免因為繫結變數的差異導致存在多種最優執行計劃的問題無法被發現的問題出現。如果前五次編譯發現存在通用執行計劃,那麼這個通用執行計劃就會被共享。我們來看下面的例子。

 

我們可以看到,在前面五次執行的時候 o bject_id 都是代入具體得值的,而第六次執行就變成 $ 1 ,這就是使用了通用執行計劃。我們再來看一個複雜一些的例子。

 

從這個例子上可以看到,如果繫結變數出現了較大的差異,那麼 Postgre SQL 不會一味的用通用執行計劃去套用,而是會使用 c ustom 執行計劃,透過全表掃描來替代索引掃描,從而確保 S QL 的高效執行,這和 Oracle的Adaptive   Cursor   sharing的思路基本上是一致的。

 


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

相關文章