CREATE STATISTICS
— 定義擴充套件統計資訊
CREATE STATISTICS [ [ IF NOT EXISTS ]statistics_name
] ON (expression
) FROMtable_name
CREATE STATISTICS [ [ IF NOT EXISTS ]statistics_name
] [ (statistics_kind
[, ... ] ) ] ON {column_name
| (expression
) }, {column_name
| (expression
) } [, ...] FROMtable_name
CREATE STATISTICS
命令將建立一個新的擴充套件統計資訊物件,用於跟蹤指定表、外部表或物化檢視的資料。此統計資訊物件將在當前資料庫中建立,並由發出命令的使用者擁有。
CREATE STATISTICS
命令有兩種基本形式。第一種形式允許收集單個表示式的單變數統計資訊,其好處類似於表示式索引,但沒有索引維護的開銷。此形式不允許指定統計資訊種類,因為各種統計資訊種類僅指多變數統計資訊。該命令的第二種形式允許收集多個列和/或表示式的多變數統計資訊,並可選擇指定要包含的統計資訊種類。此形式還將自動收集列表中包含的任何表示式的單變數統計資訊。
如果給出了模式名(例如,CREATE STATISTICS myschema.mystat ...
),則統計資訊物件將在指定的模式中建立。否則,它將在當前模式中建立。如果給出了統計資訊物件的名稱,則該名稱在同一模式中的任何其他統計資訊物件名稱都必須不同。
IF NOT EXISTS
如果已存在同名統計資訊物件,則不報錯,而是發出通知。請注意,這裡只考慮統計資訊物件的名稱,而不考慮其定義的詳細資訊。當指定 IF NOT EXISTS
時,統計資訊名稱是必需的。
statistics_name
要建立的統計資訊物件的名稱(可選模式限定)。如果省略名稱,PostgreSQL 將根據父表名稱以及定義的列名稱和/或表示式選擇一個合適的名稱。
statistics_kind
在此統計資訊物件中計算的多變數統計資訊種類。當前支援的種類有:ndistinct
,它啟用 n-distinct 統計資訊;dependencies
,它啟用函式依賴統計資訊;以及 mcv
,它啟用最常見值列表。如果省略此子句,則所有支援的統計資訊種類都將包含在此統計資訊物件中。如果統計資訊定義包含複雜的表示式而不是簡單的列引用,則會自動構建單變量表達式統計資訊。有關更多資訊,請參閱 第 14.2.2 節 和 第 69.2 節。
column_name
將被計算的統計資訊覆蓋的表列的名稱。僅在構建多變數統計資訊時允許。至少必須指定兩個列名或表示式,它們的順序不重要。
expression
將被計算的統計資訊覆蓋的表示式。這可以用於為單個表示式構建單變數統計資訊,或作為構建多變數統計資訊的多個列名和/或表示式列表的一部分。在後一種情況下,列表中的每個表示式都會自動構建單獨的單變數統計資訊。
table_name
用於計算統計資訊的表(可選模式限定)的名稱;請參閱 ANALYZE 以瞭解繼承和分割槽的處理方式。
要建立讀取它的表上的統計資訊物件,您必須是該表的擁有者。但是,一旦建立,統計資訊物件的所有權就獨立於底層表。
表示式統計資訊是按表示式計算的,類似於在表示式上建立索引,不同之處在於它們避免了索引維護的開銷。表示式統計資訊會為統計資訊物件定義中的每個表示式自動構建。
當前規劃器不使用擴充套件統計資訊來估算表連線的選擇性。此限制將來可能會在 PostgreSQL 的新版本中被移除。
建立表 t1
,該表有兩個函式依賴的列,即,瞭解第一個列的值足以確定第二個列的值。然後,將在這些列上構建函式依賴統計資訊。
CREATE TABLE t1 ( a int, b int ); INSERT INTO t1 SELECT i/100, i/500 FROM generate_series(1,1000000) s(i); ANALYZE t1; -- the number of matching rows will be drastically underestimated: EXPLAIN ANALYZE SELECT * FROM t1 WHERE (a = 1) AND (b = 0); CREATE STATISTICS s1 (dependencies) ON a, b FROM t1; ANALYZE t1; -- now the row count estimate is more accurate: EXPLAIN ANALYZE SELECT * FROM t1 WHERE (a = 1) AND (b = 0);
如果沒有函式依賴統計資訊,規劃器會假設兩個 WHERE
子句是獨立的,並將它們的選擇性相乘,從而得到一個低得離譜的行數估算。有了這樣的統計資訊,規劃器就會識別出 WHERE
子句是冗餘的,就不會低估行數。
建立表 t2
,該表有兩個完全相關的列(包含相同的資料),並在這些列上建立 MCV 列表。
CREATE TABLE t2 ( a int, b int ); INSERT INTO t2 SELECT mod(i,100), mod(i,100) FROM generate_series(1,1000000) s(i); CREATE STATISTICS s2 (mcv) ON a, b FROM t2; ANALYZE t2; -- valid combination (found in MCV) EXPLAIN ANALYZE SELECT * FROM t2 WHERE (a = 1) AND (b = 1); -- invalid combination (not found in MCV) EXPLAIN ANALYZE SELECT * FROM t2 WHERE (a = 1) AND (b = 2);
MCV 列表為規劃器提供了關於表中常見值的具體值的更詳細資訊,以及對未出現在表中的值組合的選擇性的上限,從而使它在這兩種情況下都能生成更好的估算。
建立表 t3
,該表有一個單獨的時間戳列,並對該列上的表示式執行查詢。如果沒有擴充套件統計資訊,規劃器將不知道表示式的資料分佈資訊,並使用預設估算。規劃器也不知道按月份截斷的日期值完全由按天截斷的日期值確定。然後,將在這兩個表示式上構建表示式和 ndistinct 統計資訊。
CREATE TABLE t3 ( a timestamp ); INSERT INTO t3 SELECT i FROM generate_series('2020-01-01'::timestamp, '2020-12-31'::timestamp, '1 minute'::interval) s(i); ANALYZE t3; -- the number of matching rows will be drastically underestimated: EXPLAIN ANALYZE SELECT * FROM t3 WHERE date_trunc('month', a) = '2020-01-01'::timestamp; EXPLAIN ANALYZE SELECT * FROM t3 WHERE date_trunc('day', a) BETWEEN '2020-01-01'::timestamp AND '2020-06-30'::timestamp; EXPLAIN ANALYZE SELECT date_trunc('month', a), date_trunc('day', a) FROM t3 GROUP BY 1, 2; -- build ndistinct statistics on the pair of expressions (per-expression -- statistics are built automatically) CREATE STATISTICS s3 (ndistinct) ON date_trunc('month', a), date_trunc('day', a) FROM t3; ANALYZE t3; -- now the row count estimates are more accurate: EXPLAIN ANALYZE SELECT * FROM t3 WHERE date_trunc('month', a) = '2020-01-01'::timestamp; EXPLAIN ANALYZE SELECT * FROM t3 WHERE date_trunc('day', a) BETWEEN '2020-01-01'::timestamp AND '2020-06-30'::timestamp; EXPLAIN ANALYZE SELECT date_trunc('month', a), date_trunc('day', a) FROM t3 GROUP BY 1, 2;
如果沒有表示式和 ndistinct 統計資訊,規劃器將不知道表示式的唯一值數量,並且必須依賴預設估算。相等和範圍條件被假定為 0.5% 的選擇性,並且表示式的唯一值數量被假定與列的唯一值數量相同(即唯一)。這導致前兩個查詢的行數估算顯著偏低。此外,規劃器對錶達式之間的關係沒有資訊,因此它假設兩個 WHERE
和 GROUP BY
條件是獨立的,並將它們選擇性相乘,從而導致聚合查詢的組計數嚴重高估。這由於表示式缺乏準確的統計資訊而進一步加劇,迫使規劃器使用從列的 ndistinct 估算派生的表示式的預設 ndistinct 估算。有了這樣的統計資訊,規劃器就能識別出這些條件是相關的,並得到更準確的估算。
SQL 標準中沒有 CREATE STATISTICS
命令。
如果您在文件中發現任何不正確、與您對特定功能的使用體驗不符或需要進一步澄清的內容,請使用 此表格 報告文件問題。