漢数字型 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)
お、こんどは上手く動作した。推定行も妥当な数値だと思う。