pg的sql統計信息,慢查詢等


背景

數據庫運維過程中,dba都比較關注sql的執行時間。研發在數據庫應用開發上,速度慢的sql比比皆是,很多速度很慢都是sql寫得不好,效率不高,執行過程中也會造成數據庫的負載過大。比如無用的去重,無效的條件,不必要的子查詢,sql用不上的索引。而對於這些不符合要求的sql,首先要去把這些sql找出來。

措施

pg數據庫提供了統計信息的功能來查找,下面介紹兩種辦法:

  • 修改日志參數,記錄超過指定時間的sql,以及當時的執行時間
  • 通過pg_stat_statements統計

修改日志參數

log_min_duration_statement:從log中找出執行超過一定時間的sql。這個參數是設置執行最小多長時間的sql輸出到log,例如輸出執行超過3秒的sql,可以設置log_min_duration_statement = 3s。這個參數設置為-1是無效,默認為-1。設置為0是輸出所有的sql,但這樣會增加服務器的負擔,一般不要設置太低的值。

auto_explain功能:在Postgresql8.4版本后新增了該功能。默認這個功能是不可用的,需要配置如下。這樣系統在執行的時候遇到超過2秒的SQL的話,,會自動把sql輸出到log,這樣看log就更容易找到問題點了。

shared_preload_libraries = 'auto_explain'
custom_variable_classes = 'auto_explain'   #PostgreSQL9.2版本后此參數已取消,不需要設置
auto_explain.log_min_duration = 2s

實際log查看:

< 2019-11-12 15:40:30.284 CST > 日志:  執行時間: 3048.397 ms 語句: SELECT * FROM indexedresult WHERE searchtitle LIKE '%好%' ORDER BY  searchtitle

加載pg_stat_statements模塊

pg_stat_statements模塊提供了一種方法,用於跟蹤所有由服務器執行的sql語句的統計,例如,語句總調用次數,總執行時間,從內存中讀取的塊數,從磁盤讀取的塊數等信息。在添加或刪除模塊pg_stat_statements模塊時,需要額外的共享內存,所以必須重啟數據庫。pg_stat_statements模塊加載會消耗部分的內存,可以通過pg_stat_statements.max * track_activity_query_size來計算。這個值是比較小的,假如pg_stat_statements.max 值為 10000, track_activity_query_size值為4096,也就消耗了40M內存。

參考配置如下:

shared_preload_libraries = 'pg_stat_statements '
track_activity_query_size = 4096                #SQL文本的最大大小,4K
custom_variable_classes = 'pg_stat_statements '  #PostgreSQL9.2版本后此參數已取消,不需要設置
pg_stat_statements.max = 10000                #跟蹤模塊中的語句的最大數目
pg_stat_statements.track = all

參數配置好后,需要重啟數據庫。注意該模塊是區分數據庫的,不是全局共享的。如果無法查詢,可能需要在對應的數據庫下面加載pg_stat_statements模塊。運行如下語句:

CREATE EXTENSION pg_stat_statements;

配置好pg_stat_statements模塊后,經過一段時間的運行,我們就可以通過pg_stat_statements視圖來統計效率低的SQL,語句如下:

--查詢語句總調用次數大於10次,平均運行時間倒序的SQL
SELECT t.userid,
        t.dbid,
        t.query || ';',
        t.calls,
        t.total_time,
        t.rows,
        t.total_time / t.calls
  FROM pg_stat_statements t
 WHERE (t.calls IS NOT NULL OR t.calls <> 0)
   AND t.query !~ '^COPY|<insufficient privilege'
   AND t.calls > 10
 ORDER BY 7 DESC;

總結

上面兩種方法可以根據實際業務需要來進行,比如僅僅需要查看問題sql的情況可以用第一種,如果需要深入分析sql的類別,執行次數,執行時間等更豐富的信息可以采用第二種方式,根據調用的次數來設計緩存也是非常重要的依據。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM