天天看點

pageinsepect分析brin索引

brin索引是postgresql9.5版本中新增的功能,這個索引的特點就是占用空間特别小,原理是這樣的,它是将表的資料頁面按每128個資料塊(頁面)配置設定一條索引記錄,記錄這個區間的最大值和最小值,當你要查詢某條資料時,判斷這個值在哪個區間範圍内,找到呢條索引記錄,根據索引記錄掃描相應的128個資料塊。128這個值是預設的,在建立索引的時候可以進行調整的。下面用pageinspect這個插件對brin索引進行下簡單的分析。

postgres=# create extension pageinspect;

create extension

postgres=# create table a(id int);

create table

postgres=# insert into a select generate_series(1,3000000);

insert 0 3000000

postgres=# create index ix_a_id_brin on a using brin(id) with (pages_per_range=128);

下面看下要用到的pageinspect的函數

postgres=# df public.brin*

schema | name | result data type | argument data types

public

brin_metapage_info

record

page bytea, out magic text, out version integer, out pagesperrange integer, out lastrevmappage bigi

nt

normal

brin_page_items

setof record

page bytea, index_oid regclass, out itemoffset integer, out blknum integer, out attnum integer, out

allnulls boolean, out hasnulls boolean, out placeholder boolean, out value text

brin_page_type

text

page bytea

brin_revmap_data

setof tid

page bytea, out pages tid

brin_page_type這個是檢視索引頁面類型的,主要有三種類型meta,revmap和regular,因為這個索引隻有三個頁面是以隻看了0,1,2這三個頁面。

postgres=# select * from brin_page_type(get_raw_page('ix_a_id_brin',0));

meta

(1 row)

postgres=# select * from brin_page_type(get_raw_page('ix_a_id_brin',1));

revmap

postgres=# select * from brin_page_type(get_raw_page('ix_a_id_brin',2));

regular

postgres=# select relpages from pg_class where relname='ix_a_id_brin';

下面看下這三個頁面都是存的什麼資料。

postgres=# select * from brin_metapage_info(get_raw_page('ix_a_id_brin',0));

magic

version

pagesperrange

lastrevmappage

0xa8109cfa

1

128

這個是說這個brin索引記錄128個塊中值得範圍大小,最後一個revmap頁面是1号頁面。和之前檢視頁面類型頁面号對應。

postgres=# select * from brin_revmap_data(get_raw_page('ix_a_id_brin',1)) limit 10;

(2,1)

(2,2)

(2,3)

(2,4)

(2,5)

(2,6)

(2,7)

(2,8)

(2,9)

(2,10)

(10 rows)

postgres=# select * from brin_revmap_data(get_raw_page('ix_a_id_brin',1)) offset 100 limit 10;

(2,101)

(2,102)

(2,103)

(2,104)

(0,0)

postgres=# select count(1) from brin_revmap_data(get_raw_page('ix_a_id_brin',1)) ;

1360

postgres=# select relpages from pg_class where relname='a';

revmap頁面能存儲1360條記錄,可以看到最後一條記錄是104,這個104是怎麼算的呢?

首先查出a表一共的頁面數13275,brin索引的每條記錄對應128個塊,13275/128=103.7,是以是104。

這個還可以看出索引條目在regluar頁面的分布情況,因為我測試的記錄條數較少,是以都在2号regluar頁面上。

postgres=# select * from brin_page_items(get_raw_page('ix_a_id_brin',2),'ix_a_id_brin') limit 10;

postgres=# select * from brin_page_items(get_raw_page('ix_a_id_brin',2),'ix_a_id_brin') offset 94 limit 10;

blknum是該索引記錄對應的起始頁面編号,第一條就是0,第二條就是128。attnum是指存放第幾個字段的意思,我隻有一個字段是以都是1,allnulls表示是不是都是空值,hasnulls表示是否存在空值。value就是記錄索引對應的128個資料塊中資料的最大值和最小值。

繼續閱讀