一、視圖pg_ststs查詢可選性
1、當可選性較小時,可以用視圖pg_ststs來查詢
?表的每一列的MVC(most Common Value)作為一對most_common_vals和most_common_freqs的列存儲在pg_ststs視圖中。
?????? (1)most_common_vals:最常見的值。是統計MCVs列表的列;
?????? (2)most_common_freqs:最常見值的頻率。是統計MCV頻率的列。
2、舉個例子:使用視圖pg_ststs來查詢Selectivity
?????? 有一個表“countries”,記錄了六大洲的信息:Africa、Europe、Asia、“North America”、Oceanic、“South America”,以及每個洲包含的所有國家。
?????? 此時如果使用SQL:SELECT * FROM countries WHERE continent='Asia';那么這個亞洲城市的可選性是多少呢?
計算結果內容如下:
上圖第三列就是可選性,即:亞洲名下所有國家的個數占總國家個數的比例。總結:
?????? 與“亞洲”對應的最常見頻率值為0.227979。因此,在該估計中使用0.227979作為選擇性;
?????? 對于列值可選項很高的情況,就不能使用MCV,則使用目標列的直方圖界限值來估計成本。
此時,可以使用視圖pg_ststs可以直接對可選性進行查詢:
\x
SELECT most_common_vals,most_common_freqs
FROM pg_stats
WHERE tablename='countries'
AND attname='continent';
二、直方圖histogram_bounds查詢可選性
直方圖histogram_bounds是一個值列表,用于將列的值分成大致相等的總體組。
當可選性很高的時候,可以使用此方法來查詢。
1、Buckets and histogram_bounds
桶和直方圖邊界
如上圖所示,默認情況下,直方圖界限會劃分為100個桶, bucket從0開始編號:
bucket_0~ bucket_99,0~99就是桶id。每個桶(bucket)存儲大約相同數量的元組。
每個桶都有其最小值和最大值(下方對于的數即為其最小值)。直方圖界限的值也是相應存儲桶的界限。例如,直方圖上界的第0個值是1,這意味著它是存儲在bucket_0中的元組的最小值;第1個值是100,這是存儲在bucket_1中的元組的最小值,依此類推。
2、PG中直方圖的計算公式為
Selectivity={ bucket_id + (目標數值-hb[n])/( hb[n+1]-hb[n])} / 桶個數
#bucket_id:where子句中,限定的數值,所在的桶id
#目標數值:where子句中,限定的數值
#hb[n]:where子句中,限定的數值,所在的桶的最小界限值
#hb[n+1]:where子句中,限定的數值,所在桶的下一個桶的最小界限值
#桶個數:一共有多少個桶
SELECT histogram_bounds
FROM pg_stats
WHERE tablename='tbl'
AND attname='data';
3、舉個栗子:使用直方圖histogram_bounds來查詢Selectivity
假設存在圖內所示的數據:
使用WHERE data<240來計算選擇性(Selectivity)時,公式如下:
bucket_id=2(240在hb(2)里)
目標數值=240
hb[n]=200? (hb(2)桶內的最小值)
hb[n+1]=300? ?(hb(3)桶內的最小值)
Selectivity={ 2+ (240-200)?/ (300-200) } / 100 = 0.024