02.02 「PostgreSQL」最有用的PostgreSQL擴展:pg


「PostgreSQL」最有用的PostgreSQL擴展:pg_stat_statements


擴展能夠擴展,更改和推進Postgres的行為。 怎麼樣? 通過掛鉤到低級的Postgres API掛鉤。 可以水平擴展Postgres的開源Citus數據庫本身是作為PostgreSQL擴展實現的,這使Citus可以與Postgres版本保持最新,而不會像其他Postgres fork那樣落後。 儘管我想更深入地研究最有用的Postgres擴展:pg_stat_statements,但我之前已經寫過各種擴展類型。

你看,我剛從FOSDEM回來。 FOSDEM是在布魯塞爾舉行的年度免費開源軟件會議,在活動中,我在PostgreSQL開發室中發表了有關Postgres擴展的演講。 到今天結束時,Postgres開發室中進行的一半以上的討論都提到了pg_stat_statements:

如果您使用Postgres,但尚未使用pg_stat_statements,則必須將其添加到工具箱中。而且,即使您很熟悉,也可能值得重溫。

pg_stat_statements入門

Pg_stat_statements是所謂的contrib擴展名,可以在PostgreSQL發行版的contrib目錄中找到。這意味著它已經隨Postgres一起提供了,您無需從源代碼構建它或安裝軟件包。如果尚未啟用數據庫,則可能必須啟用它。這很簡單:

CREATE EXTENSION pg_stat_statements;

如果您在主要的雲提供商上運行,則很有可能他們已經為您安裝並啟用了它。

一旦安裝了pg_stat_statements,它就會開始悄悄地在後臺運行。 Pg_stat_statements記錄針對您的數據庫運行的查詢,從中刪除一些變量,然後保存有關該查詢的數據,例如花費了多長時間以及基礎讀/寫發生了什麼。

注意:它不會保存每個查詢,而是對其進行參數化,然後保存彙總結果

讓我們來看幾個示例。假設我們執行以下查詢:

SELECT order_details.qty, order_details.item_id, order_details.item_price FROM order_details, customers WHERE customers.id = order_details.customer_id AND customers.email = '[email protected]'

它將查詢轉換為:

SELECT order_details.qty, order_details.item_id, order_details.item_price FROM order_details, customers WHERE customers.id = order_details.customer_id AND customers.email = '?'

如果這是我在應用程序中經常執行的查詢,以獲取諸如零售訂單歷史記錄之類的訂單詳細信息,那麼它不會節省我為每個用戶運行該訂單的頻率,而是節省了彙總視圖。

看數據

從這裡我們可以查詢pg_stat_statements的原始數據,我們將看到類似以下內容:

SELECT * FROM pg_stat_statements; userid | 16384 dbid | 16388 query | select * from users where email = ?; calls | 2 total_time | 0.000268 rows | 2 shared_blks_hit | 16 shared_blks_read | 0 shared_blks_dirtied | 0 shared_blks_written | 0 local_blks_hit | 0 local_blks_read | 0 local_blks_dirtied | 0 local_blks_written | 0 ...

使用pg_stat_statements提取見解

現在,這裡有大量有價值的信息,作為高級用戶,有時它們都可以證明是有價值的。但是,即使沒有開始理解數據庫的內部結構,您仍然可以通過以某些方式查詢pg_stat_statements來獲得一些真正強大的見解。通過查看total_time和每個查詢被調用一次的次數,我們可以非常快速地查看哪些查詢經常運行以及它們平均消耗了多少:

SELECT (total_time / 1000 / 60) as total, (total_time/calls) as avg, query FROM pg_stat_statements ORDER BY 1 DESC LIMIT 100;

您可以通過多種不同的方式對此進行過濾和排序,您可能只想關注運行1000多次的查詢。或平均超過100毫秒的查詢。上面的查詢向我們顯示了數據庫消耗的總時間(以分鐘為單位)以及平均時間(以毫秒為單位)。通過上面的查詢,我會得到類似以下內容的信息:

total | avg | query --------+--------+------------------------- 295.76 | 10.13 | SELECT id FROM users... 219.13 | 80.24 | SELECT * FROM ... (2 rows)

根據經驗,我知道快速獲取記錄時,PostgreSQL應該能夠在1ms內返回。鑑於此,我可以開始優化工作。在上面的內容中,我看到將第一個查詢降低到1ms會有所改善,但是優化第二個查詢將對整個系統的性能產生更大的提升。

特別說明:如果要構建多租戶應用,則可能不希望pg_stat_statements參數化tenant_id。為了解決這個問題,我們構建了citus_stat_statements來為每個租戶提供見解。

原文:https://www.citusdata.com/blog/2019/02/08/the-most-useful-postgres-extension-pg-stat-statements/

本文:http://jiagoushi.pro/node/930

討論:請加入知識星球或者微信圈子【首席架構師圈】


分享到:


相關文章: