PostgreSQL ANALYZE

2021-09-08 17:28 更新

ANALYZE — 收集有關(guān)一個(gè)數(shù)據(jù)庫的統(tǒng)計(jì)信息

大綱

ANALYZE [ ( option [, ...] ) ] [ table_and_columns [, ...] ]
ANALYZE [ VERBOSE ] [ table_and_columns [, ...] ]

其中option可以是:

    VERBOSE [ boolean ]
    SKIP_LOCKED [ boolean ]

table_and_columns是:

    table_name [ ( column_name [, ...] ) ]

描述

ANALYZE收集一個(gè)數(shù)據(jù)庫中的表的內(nèi)容的統(tǒng)計(jì)信息,并且將結(jié)果存儲在pg_statistic系統(tǒng)目錄中。接下來,查詢規(guī)劃器會使用這些統(tǒng)計(jì)信息來幫助確定查詢最有效的執(zhí)行計(jì)劃。

如果沒有table_and_columns列表,則ANALYZE處理當(dāng)前用戶有權(quán)分析的當(dāng)前數(shù)據(jù)庫中的每個(gè)表和物化視圖。使用列表,ANALYZE僅處理那些表。還可以給出表的列名列表,在這種情況下,僅收集這些列的統(tǒng)計(jì)信息。

當(dāng)選項(xiàng)列表用括號括起來時(shí),選項(xiàng)可以按任何順序來寫。 帶括號的語法是在PostgreSQL 11中添加的;不帶括號的語法已棄用。

參數(shù)

VERBOSE

允許顯示進(jìn)度消息。

SKIP_LOCKED

規(guī)定ANALYZE在開始處理一個(gè)關(guān)系時(shí)不應(yīng)等待任何沖突的鎖被釋放:如果關(guān)系不能無需等待立即鎖定,則跳過該關(guān)系。 請注意即使采用此選項(xiàng),ANALYZE在打開關(guān)系的索引或從分區(qū)、表繼承子級和某些類型的外表獲取樣本行時(shí)仍可能阻塞。 此外,當(dāng)ANALYZE通常處理指定分區(qū)表的所有分區(qū)時(shí),如果分區(qū)表上有一個(gè)沖突的鎖,這個(gè)選項(xiàng)將導(dǎo)致 ANALYZE跳過所有分區(qū)表。

boolean

規(guī)定所選的選項(xiàng)打開或關(guān)閉。 您可以寫TRUE、ON1以啟用該選項(xiàng),或者是FALSEOFF0來禁用它。 boolean 值可以被省略,在假定為 TRUE的情況下。

table_name

要分析的一個(gè)指定表的名稱(可以是模式限定的)。如果省略,則分析當(dāng)前數(shù)據(jù)庫中的所有常規(guī)表、分區(qū)表和物化視圖(但不包含外部表)。 如果指定的表是分區(qū)表,則整個(gè)分區(qū)表的繼承統(tǒng)計(jì)信息和各個(gè)分區(qū)的統(tǒng)計(jì)信息都將更新。

column_name

要分析的一個(gè)指定列的名稱。默認(rèn)是所有列。

輸出

當(dāng)指定了VERBOSE時(shí),ANALYZE會發(fā)出進(jìn)度消息來指示當(dāng)前正在處理哪個(gè)表。還會打印有關(guān)那些表的多種統(tǒng)計(jì)信息。

注解

要分析表,通常必須是該表的所有者或超級用戶。不過,數(shù)據(jù)庫所有者可以分析數(shù)據(jù)庫中的所有表,共享目錄除外。 (對共享目錄的限制意味著真正的數(shù)據(jù)庫范圍的ANALYZE只能由超級用戶執(zhí)行。) ANALYZE將跳過調(diào)用用戶沒有分析權(quán)限的任何表。

只有被顯式選中時(shí)才會分析外部表。并非所有外部數(shù)據(jù)包裝器都支持ANALYZE。如果表的包裝器不支持ANALYZE,該命令會打印一個(gè)警告并且什么也不做。

在默認(rèn)的PostgreSQL配置中,自動(dòng)清理守護(hù)進(jìn)程(見第 24.1.6 節(jié))會在表第一次載入數(shù)據(jù)或者用常規(guī)操作改變時(shí)負(fù)責(zé)表的自動(dòng)分析。當(dāng)啟用自動(dòng)清理時(shí),定期運(yùn)行ANALYZE是個(gè)好主意,或者可以在表內(nèi)容做了大的修改后運(yùn)行 ANALYZE。準(zhǔn)確的統(tǒng)計(jì)信息將幫助規(guī)劃器選擇最合適的查詢計(jì)劃,從而提升查詢處理的速度。主讀數(shù)據(jù)庫的一般策略是在一天中使用量最低時(shí)運(yùn)行一次VACUUMANALYZE(如果有大量的更新動(dòng)作則是不夠的)。

ANALYZE只要求目標(biāo)表上的一個(gè)讀鎖,因此它可以和表上的其他動(dòng)作并行。

ANALYZE收集的統(tǒng)計(jì)信息通暢包括每列中最常見值的列表以及展示每列中近似數(shù)據(jù)分布的一個(gè)直方圖。如果ANALYZE認(rèn)為這些東西無趣(例如在一個(gè)唯一鍵列中,沒有共同值)或者該列的數(shù)據(jù)類型不支持合適的操作符,以上工作都會被省略。在第 24 章中有與統(tǒng)計(jì)信息相關(guān)的更多信息。

對于大型的表,ANALYZE會對表內(nèi)容做隨機(jī)采樣而不是檢查每一行。這允許在很少的時(shí)間內(nèi)完成對大型表的分析。不過要注意,這些統(tǒng)計(jì)信息只是近似值,并且即使實(shí)際表內(nèi)容沒有改變,每次運(yùn)行ANALYZE時(shí)統(tǒng)計(jì)信息都會有微小地改變。這可能會導(dǎo)致EXPLAIN顯示的規(guī)劃器估算代價(jià)有小的改變。在很少的情況下,這會非決定性地導(dǎo)致規(guī)劃器的查詢計(jì)劃選擇在 ANALYZE運(yùn)行后改變。為了避免這種情況,可以按照下文所述提高ANALYZE所收集的統(tǒng)計(jì)信息量。

通過調(diào)整default_statistics_target配置變量可以控制分析量,對每個(gè)列可以用ALTER TABLE ... ALTER COLUMN ... SET STATISTICS設(shè)置每列的統(tǒng)計(jì)信息目標(biāo)(見ALTER TABLE)。目標(biāo)值會設(shè)置最常用值列表中的最大項(xiàng)數(shù)以及直方圖中的最大容器數(shù)。默認(rèn)目標(biāo)值是 100,可以把它調(diào)大或者調(diào)小在規(guī)劃器估計(jì)值精度和ANALYZE花費(fèi)的時(shí)間以及pg_statistic所占空間之間做出平衡。特別地,將統(tǒng)計(jì)信息目標(biāo)設(shè)置為零會禁用該列的統(tǒng)計(jì)信息收集。在查詢的 WHERE、GROUP BY或者ORDER BY子句中從不出現(xiàn)的列上這樣做會有所幫助,因?yàn)橐?guī)劃器用不上這些列上的統(tǒng)計(jì)信息。

被分析的列中最大的統(tǒng)計(jì)信息目標(biāo)決定了為準(zhǔn)備統(tǒng)計(jì)信息要采樣的表行數(shù)。增加該目標(biāo)會導(dǎo)致做ANALYZE所需的時(shí)間和空間成比例增加。

ANALYZE所估算的值之一是出現(xiàn)在每個(gè)列中的可區(qū)分值。因?yàn)橹粫z查行的一個(gè)子集,即便使用最大的統(tǒng)計(jì)信息目標(biāo),這種估計(jì)有時(shí)也可能很不精確。如果這種不精確導(dǎo)致不好的查詢計(jì)劃,可以手工確定一個(gè)更精確的值并且用ALTER TABLE ... ALTER COLUMN ... SET (n_distinct = ...)設(shè)置該值(見ALTER TABLE)。

如果被分析的表有一個(gè)或者更多子女,ANALYZE將會收集兩次統(tǒng)計(jì)信息:一次只對父表的行收集,第二次則在父表及其所有子女表的行上收集。在規(guī)劃需要遍歷整個(gè)繼承樹的查詢時(shí)需要第二個(gè)統(tǒng)計(jì)信息集。不過,在決定是否觸發(fā)表上的自動(dòng)分析時(shí),自動(dòng)清理后臺進(jìn)程將只考慮父表本身上的插入和更新。如果該表很少被插入或者更新,只有手工運(yùn)行ANALYZE時(shí)才會把繼承統(tǒng)計(jì)信息更新到最新。

如果任何子表是外部表并且其外部數(shù)據(jù)包裝器不支持ANALYZE,在收集繼承統(tǒng)計(jì)信息時(shí)會忽略那些子表。

如果被分析的表不完全為空,ANALYZE將不會為該表記錄新統(tǒng)計(jì)信息。任何現(xiàn)有統(tǒng)計(jì)信息將會被保留。

兼容性

SQL 標(biāo)準(zhǔn)中沒有ANALYZE語句。


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

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號