PostgreSQL auto_explain

2021-09-16 15:27 更新
F.4.1. 配置參數(shù)
F.4.2. 例子
F.4.3. 作者

auto_explain模塊提供了一種方式來自動(dòng)記錄慢速語(yǔ)句的執(zhí)行計(jì)劃,而不需 要手工運(yùn)行EXPLAIN。這在大型應(yīng)用中追蹤未被優(yōu)化的查詢時(shí)有用。

該模塊沒有提供 SQL 可訪問的函數(shù)。要使用它,簡(jiǎn)單地將它載入服務(wù)器。你可以把它載入到一個(gè)單獨(dú)的 會(huì)話:

LOAD 'auto_explain';

(你必須作為超級(jí)用戶來這樣做)。更典型的用法是通過在postgresql.confsession_preload_librariesshared_preload_libraries參數(shù)中包括 auto_explain將它預(yù)先 載入到某些或者所有會(huì)話中。然后你就可以追蹤那些出乎意料地慢的查詢,而不管它們何時(shí)發(fā)生。當(dāng)然為 此會(huì)付出一些額外的負(fù)荷作為代價(jià)。

F.4.1. 配置參數(shù)

有幾個(gè)配置參數(shù)用來控制auto_explain的行為。注意默認(rèn)行為是什么也不做,因此如果你想要任何結(jié)果就必須至少設(shè)置auto_explain.log_min_duration。

auto_explain.log_min_duration (integer)

auto_explain.log_min_duration是最小語(yǔ)句執(zhí)行時(shí)間(以毫秒計(jì)),這將導(dǎo)致語(yǔ)句的計(jì)劃被記錄。這個(gè)參數(shù)設(shè)置為0時(shí)將記錄所有計(jì)劃,設(shè)置為-1(默認(rèn)值)時(shí)禁用記錄計(jì)劃。例如,如果你將它設(shè)置為250ms,則所有運(yùn)行時(shí)間等于或超過 250ms 的語(yǔ)句將被記錄。只有超級(jí)用戶能夠改變這個(gè)設(shè)置。

auto_explain.log_analyze (boolean)

當(dāng)一個(gè)執(zhí)行計(jì)劃被記錄時(shí),auto_explain.log_analyze導(dǎo)致EXPLAIN ANALYZE輸出(而不僅僅是EXPLAIN輸出)被打印。默認(rèn)情況下這個(gè)參數(shù)是關(guān)閉的。只有超級(jí)用戶能夠改變這個(gè)設(shè)置。

注意

當(dāng)這個(gè)參數(shù)為打開時(shí),對(duì)所有被執(zhí)行的語(yǔ)句將引起對(duì)每個(gè)計(jì)劃節(jié)點(diǎn)的計(jì)時(shí),不管它們是否運(yùn)行得足夠長(zhǎng)以至于被記錄。這可能對(duì)性能有極度負(fù)面的影響。

auto_explain.log_buffers (boolean)

當(dāng)一個(gè)執(zhí)行計(jì)劃被記錄時(shí),auto_explain.log_buffers控制是否打印 緩沖區(qū)使用統(tǒng)計(jì)信息;它等效于EXPLAINBUFFERS選項(xiàng)。除非 auto_explain.log_analyze參數(shù)被設(shè)置,否則這個(gè)參數(shù)沒有效果。這個(gè)參數(shù)默 認(rèn)情況下是關(guān)閉的。只有超級(jí)用戶能夠改變這個(gè)設(shè)置。

auto_explain.log_wal (boolean)

auto_explain.log_wal 控制當(dāng)執(zhí)行計(jì)劃被記錄時(shí)是否打印WAL使用情況統(tǒng)計(jì)信息; 它相當(dāng)于EXPLAINWAL 選項(xiàng)。 除非啟用了auto_explain.log_analyze,否則這個(gè)參數(shù)不生效。 這個(gè)參數(shù)默認(rèn)是關(guān)閉狀態(tài)。只有超級(jí)用戶能夠改變這個(gè)設(shè)置。

auto_explain.log_timing (boolean)

當(dāng)一個(gè)執(zhí)行計(jì)劃被記錄時(shí),auto_explain.log_timing控制是否打印每 個(gè)結(jié)點(diǎn)上的計(jì)時(shí)信息;它等效于EXPLAINTIMING選項(xiàng)。重復(fù)讀取 系統(tǒng)鎖的開銷在某些系統(tǒng)上可能會(huì)顯著地拖慢查詢,因此當(dāng)只需要實(shí)際行計(jì)數(shù)而非確切時(shí)間時(shí),關(guān)閉 這個(gè)參數(shù)將會(huì)很有幫助。只有當(dāng)auto_explain.log_analyze也被啟用 時(shí)這個(gè)參數(shù)才有效。這個(gè)參數(shù)默認(rèn)情況下是打開的。只有超級(jí)用戶能夠改變這個(gè)設(shè)置。

auto_explain.log_triggers (boolean)

當(dāng)一個(gè)執(zhí)行計(jì)劃被記錄時(shí),auto_explain.log_triggers會(huì)導(dǎo)致觸發(fā) 器執(zhí)行統(tǒng)計(jì)信息被包括在內(nèi)。只有當(dāng)auto_explain.log_analyze也被 啟用時(shí)這個(gè)參數(shù)才有效。這個(gè)參數(shù)默認(rèn)情況下是關(guān)閉的。只有超級(jí)用戶能夠改變這個(gè)設(shè)置。

auto_explain.log_verbose (boolean)

當(dāng)一個(gè)執(zhí)行計(jì)劃被記錄時(shí),auto_explain.log_verbose控制是否打印很長(zhǎng)的詳細(xì)信息;它等效于EXPLAINVERBOSE選項(xiàng)。這個(gè)參數(shù)默認(rèn)情況下是關(guān)閉的。只有超級(jí)用戶能夠改變這個(gè)設(shè)置。

auto_explain.log_settings (boolean)

auto_explain.log_settings控制執(zhí)行計(jì)劃被日志記錄時(shí)是否打印關(guān)于已修改的配置選項(xiàng)的信息。輸出中僅包含影響查詢計(jì)劃的選項(xiàng),其值與內(nèi)置缺省值不同。該參數(shù)默認(rèn)關(guān)閉。僅超級(jí)用戶可修改該設(shè)置。

auto_explain.log_format (enum)

auto_explain.log_format選擇要使用的EXPLAIN輸出格式。允許的值是text、xml、jsonyaml。默認(rèn)是文本形式。只有超級(jí)用戶能夠改變這個(gè)設(shè)置。

auto_explain.log_level (enum)

auto_explain.log_level選擇日志的級(jí)別,在此級(jí)別上,auto_explain會(huì)記錄查詢計(jì)劃。有效值為DEBUG5, DEBUG4,DEBUG3, DEBUG2, DEBUG1, INFO, NOTICE, WARNINGLOG。缺省為LOG。僅超級(jí)用戶可修改該設(shè)置。

auto_explain.log_nested_statements (boolean)

auto_explain.log_nested_statements導(dǎo)致嵌套語(yǔ)句(在一個(gè)函數(shù)內(nèi)執(zhí)行的語(yǔ)句)會(huì)被考慮在記錄范圍之內(nèi)。當(dāng)它被關(guān)閉時(shí),只有頂層查詢計(jì)劃被記錄。這個(gè)參數(shù)默認(rèn)情況下是關(guān)閉的。只有超級(jí)用戶能夠改變這個(gè)設(shè)置。

auto_explain.sample_rate (real)

auto_explain.sample_rate會(huì)讓 auto_explain 只解釋每個(gè)會(huì)話中的一部分語(yǔ)句。默認(rèn)值為 1,表示解釋所有的查詢。在嵌套 語(yǔ)句的情況下,要么所有語(yǔ)句都被解釋,要么一個(gè)也不被解釋。只有超級(jí)用戶 能夠更改這個(gè)設(shè)置。

在普通用法中,這些參數(shù)都在postgresql.conf中設(shè)置,不過超級(jí)用戶可以在他們自己的會(huì)話中隨時(shí)修改這些參數(shù)。典型的用法可能是:

# postgresql.conf
session_preload_libraries = 'auto_explain'

auto_explain.log_min_duration = '3s'

F.4.2. 例子

postgres=# LOAD 'auto_explain';
postgres=# SET auto_explain.log_min_duration = 0;
postgres=# SET auto_explain.log_analyze = true;
postgres=# SELECT count(*)
           FROM pg_class, pg_index
           WHERE oid = indrelid AND indisunique;

這可能會(huì)產(chǎn)生這樣的日志輸出:

LOG:  duration: 3.651 ms  plan:
  Query Text: SELECT count(*)
              FROM pg_class, pg_index
              WHERE oid = indrelid AND indisunique;
  Aggregate  (cost=16.79..16.80 rows=1 width=0) (actual time=3.626..3.627 rows=1 loops=1)
    ->  Hash Join  (cost=4.17..16.55 rows=92 width=0) (actual time=3.349..3.594 rows=92 loops=1)
          Hash Cond: (pg_class.oid = pg_index.indrelid)
          ->  Seq Scan on pg_class  (cost=0.00..9.55 rows=255 width=4) (actual time=0.016..0.140 rows=255 loops=1)
          ->  Hash  (cost=3.02..3.02 rows=92 width=4) (actual time=3.238..3.238 rows=92 loops=1)
                Buckets: 1024  Batches: 1  Memory Usage: 4kB
                ->  Seq Scan on pg_index  (cost=0.00..3.02 rows=92 width=4) (actual time=0.008..3.187 rows=92 loops=1)
                      Filter: indisunique

F.4.3. 作者

Takahiro Itagaki


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)