PostgreSQL에는 pageinspect라는 extension이 있습니다. 해당 extension을 사용하면, 테이블이나 인덱스의 실제 페이지(블록) 정보를 들여다 볼수 있습니다.

SQL STARTER 도서와 StartUP Tuning 강의에서 제공하는 실습 데이터베이스에는 tr_ord(주문)라는 테이블이 존재합니다. 해당 테이블의 인덱스를 먼저 살펴보면 다음과 같습니다.

-- [SQL-1]
SELECT  t1.*
FROM    pg_indexes t1
WHERE   t1.tablename = 'tr_ord';

schemaname|tablename|indexname  |tablespace|indexdef                                                              |
----------+---------+-----------+----------+----------------------------------------------------------------------+
startdbpg |tr_ord   |tr_ord_pk  |          |CREATE UNIQUE INDEX tr_ord_pk ON startdbpg.tr_ord USING btree (ord_no)|
startdbpg |tr_ord   |tr_ord_fk01|          |CREATE INDEX tr_ord_fk01 ON startdbpg.tr_ord USING btree (mbr_id)     |
startdbpg |tr_ord   |tr_ord_fk02|          |CREATE INDEX tr_ord_fk02 ON startdbpg.tr_ord USING btree (shop_id)    |
startdbpg |tr_ord   |tr_ord_x01 |          |CREATE INDEX tr_ord_x01 ON startdbpg.tr_ord USING btree (ord_dtm)     |

pk 인덱스인 tr_ord_pk 인덱스 구조를 pageinspect를 사용해 들여다 보려고 합니다. tr_ord_pk는 ord_no 컬럼으로 구성되어 있습니다. ord_no의 최소값과 최대값을 먼저 살펴보면 다음과 같습니다. tr_ord_pk의 리프 페이지(블록)에는 1부터 730327까지의 순번이 저장되어 있다는 사실을 알 수 있습니다.

-- [SQL-2]
select min(ord_no) min_ord_no ,max(ord_no) max_ord_no from tr_ord;

min_ord_no|max_ord_no|
----------+----------+
         1|    730327|

pk_ord_no의 인덱스 정보를 살펴보면 다음과 같습니다.

-- [SQL-3]
SELECT * FROM public.bt_metap('tr_ord_pk'::text);

magic |version|root|level|fastroot|fastlevel|last_cleanup_num_delpages|last_cleanup_num_tuples|allequalimage|
------+-------+----+-----+--------+---------+-------------------------+-----------------------+-------------+
340322|      4| 412|    2|     412|        2|                        0|                   -1.0|true         |

위 결과의 중요한 내용은 다음과 같습니다.

위 결과에서 인덱스의 루트 페이지 번호가 412라는 것을 알 수 있습니다. 해당 번호를 bt_page_items에 대입해 루트 페이지를 살펴볼 수 있습니다. 아래와 같습니다.

-- [SQL-4]
-- root 가 412
SELECT  t1.*
FROM    bt_page_items(get_raw_page('tr_ord_pk', 412)) t1;

itemoffset|ctid    |itemlen|nulls|vars |data                   |dead|htid|tids|
----------+--------+-------+-----+-----+-----------------------+----+----+----+
         1|(3,0)   |      8|false|false|                       |    |    |NULL|
         2|(411,1) |     16|false|false|77 97 01 00 00 00 00 00|    |    |NULL|
         3|(698,1) |     16|false|false|ed 2e 03 00 00 00 00 00|    |    |NULL|
         4|(984,1) |     16|false|false|63 c6 04 00 00 00 00 00|    |    |NULL|
         5|(1270,1)|     16|false|false|d9 5d 06 00 00 00 00 00|    |    |NULL|
         6|(1556,1)|     16|false|false|4f f5 07 00 00 00 00 00|    |    |NULL|
         7|(1842,1)|     16|false|false|c5 8c 09 00 00 00 00 00|    |    |NULL|

위 결과 항목별 중요 내용을 정리하면 아래와 같습니다.