監控 Postgres 查詢解析器
據我了解,當您向 Postgres 發送查詢時,例如:
SELECT id FROM table1 WHERE name = $1;
Postgres 將創建一個查詢計劃。該計劃將在同一會話中為同一查詢記憶體。但是如果你創建一個函式:
CREATE OR REPLACE FUNCTION get_table1 (parname text) RETURNS bigint LANGUAGE plpgsql AS $$BEGIN RETURN (SELECT id FROM table1 where name = parname); END$$;
查詢計劃將被記憶體用於所有未來的會話。
我想通過檢查查詢分析器被呼叫的頻率來驗證這個理論。有沒有辦法檢查 Postgres 解析查詢的次數?
如果可能的話,我想監控每秒#parses 和 min/max/avg 解析持續時間之類的東西。
無法為“所有未來的會話”保存查詢計劃。查詢計劃只為目前會話保存。並且只有在一些有利條件下才能重複使用。
即席 SQL 查詢的計劃根本不保存。PL/pgSQL 函式中的所有查詢都被視為準備好的語句。並且除了查詢計劃之外還有更多步驟。
值得注意的是,自 Postgres 9.1 以來發生了重大變化,通用計劃更普遍地被保存並重用於 PL/pgSQL 中的語句。這在 pg 9.2 中變得更加智能。
手冊(粗體強調我的):
準備好的語句僅在目前數據庫會話期間持續。
這並沒有說明查詢計劃,但是:
執行語句時
PREPARE
,對指定的語句進行 解析、分析和重寫。隨後發出命令時,計劃並執行EXECUTE
準備好的語句。再往下:
如果一條準備好的語句被執行了足夠多的時間,伺服器最終可能 會決定保存並重用一個通用計劃,而不是每次都重新計劃。如果準備好的語句沒有參數,這將立即發生;否則,只有在通用計劃似乎並不比依賴特定參數值的計劃貴很多時才會發生這種情況。通常,僅當估計查詢的性能對提供的特定參數值相當不敏感時,才會選擇通用計劃。
如何判斷是否使用通用計劃?
要檢查 PostgreSQL 用於準備好的語句的查詢計劃,請使用
EXPLAIN
. 如果使用通用計劃,它將包含參數符號$n
,而自定義計劃將目前實際參數值代入其中。保存的計劃始終是通用計劃,反之則不然。
準備好的語句保存在哪裡?
您可以通過查詢**
pg_prepared_statements
**系統視圖查看會話中所有可用的準備好的語句。PL/pgSQL 中 SQL 語句的查詢計劃
這些通常在
EXPLAIN
輸出中不可見。您也可以安裝附加模組auto-explain以將這些計劃寫入日誌。詳情在這裡:有關PL/pgSQL 函式中計劃記憶體的詳細資訊,最好直接閱讀手冊。