漢数字型 version 1.2

大量に漢数字型をデータを投入したあとでインデクスを設定しても、インデクスを使った実行計画が選択されない・・・。

INSERT INTO ksj_sample VALUES (generate_series(1,1000000), ((random() * 10000)::int)::ksj);
INSERT 0 1000000
ANALYZE ksj_sample;
ANALYZE
SET enable_seqscan = on;
SET
EXPLAIN ANALYZE SELECT id, data FROM ksj_sample WHERE data = 100::ksj ;
                                                   QUERY PLAN
----------------------------------------------------------------------------------------------------------------
 Seq Scan on ksj_sample  (cost=0.00..16925.00 rows=500000 width=8) (actual time=0.684..94.308 rows=119 loops=1)
   Filter: (data = '壱百'::ksj)
 Total runtime: 94.444 ms
(3 rows)

SET enable_seqscan = off;
SET
EXPLAIN ANALYZE SELECT id, data FROM ksj_sample WHERE data = 100::ksj ;
                                                        QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------
 Bitmap Heap Scan on ksj_sample  (cost=11167.40..21842.40 rows=500000 width=8) (actual time=0.056..0.274 rows=119 loops=1)
   Recheck Cond: (data = '壱百'::ksj)
   ->  Bitmap Index Scan on ksj_idx  (cost=0.00..11042.40 rows=500000 width=0) (actual time=0.040..0.040 rows=119 loops=1)
         Index Cond: (data = '壱百'::ksj)
 Total runtime: 0.404 ms
(5 rows)

enable_seqscan=off にすると選択はされるので、コスト推定が間違っているのだろう。選択される推定行がレコード数の1/2になっているようだ。
ということで調べてみたら、CREATE OPERATORの指定でRESTRICTIONの指定をしてなかった・・・。

ということでPostgreSQL文書に書いてあったeqsel, scalargtsel等をそれぞれの演算子に追加して再挑戦。

TRUNCATE TABLE ksj_sample;
TRUNCATE TABLE
INSERT INTO ksj_sample VALUES (generate_series(1,1000000), ((random() * 10000)::int)::ksj);
INSERT 0 1000000
ANALYZE ksj_sample;
ANALYZE
SET enable_seqscan = on;
SET
EXPLAIN ANALYZE SELECT id, data FROM ksj_sample WHERE data = 100::ksj ;
                                                    QUERY PLAN
-------------------------------------------------------------------------------------------------------------------
 Bitmap Heap Scan on ksj_sample  (cost=5.15..351.29 rows=98 width=8) (actual time=0.037..0.221 rows=101 loops=1)
   Recheck Cond: (data = '壱百'::ksj)
   ->  Bitmap Index Scan on ksj_idx  (cost=0.00..5.13 rows=98 width=0) (actual time=0.022..0.022 rows=101 loops=1)
         Index Cond: (data = '壱百'::ksj)
 Total runtime: 0.330 ms
(5 rows)

お、こんどは上手く動作した。推定行も妥当な数値だと思う。