RDBMS で実行計画を制御する方法としてはヒント句がメジャーですが、
PostgreSQL でヒント句を使用するには pg_hint_plan を導入しておく必要があります。
pg_hint_plan を (すぐに) 導入できない場合に実行計画を制御する方法として、プランナメソッド設定の変更が挙げられます。
例として、下記の SQL でインデックスを使用しないように制御したいケースを考えます。
postgres=# \d pgbench_accounts
Table "public.pgbench_accounts"
Column | Type | Collation | Nullable | Default
----------+---------------+-----------+----------+---------
aid | integer | | not null |
bid | integer | | |
abalance | integer | | |
filler | character(84) | | |
Indexes:
"pgbench_accounts_pkey" PRIMARY KEY, btree (aid)
postgres=#
postgres=# select count(1) from pgbench_accounts ;
count
----------
10000000
(1 row)
postgres=#
postgres=# explain select * from pgbench_accounts where aid between 1 and 6500000;
QUERY PLAN
----------------------------------------------------------------------------------------------------------
Index Scan using pgbench_accounts_pkey on pgbench_accounts (cost=0.43..308898.41 rows=6521899 width=97)
Index Cond: ((aid >= 1) AND (aid <= 6500000))
(2 rows)
postgres=#
プランナメソッド設定の一つであるenable_indexscanを OFF に変更することで、インデックスを使用しないように制御することができます。
postgres=#
postgres=# show enable_indexscan ;
enable_indexscan
------------------
on
(1 row)
postgres=#
postgres=# set enable_indexscan = 'off';
SET
postgres=#
postgres=# show enable_indexscan ;
enable_indexscan
------------------
off
(1 row)
postgres=#
postgres=# explain select * from pgbench_accounts where aid between 1 and 6500000;
QUERY PLAN
----------------------------------------------------------------------------
Seq Scan on pgbench_accounts (cost=0.00..313935.00 rows=6521899 width=97)
Filter: ((aid >= 1) AND (aid <= 6500000))
(2 rows)
postgres=#
(参考) お遊びでenable_seqscanも OFF にすると Bitmap Heap Scan となり、
enable_bitmapscanも OFF にすると一周回って (?) Index Scan となりました。(cost は爆増)
postgres=# show enable_indexscan ;
enable_indexscan
------------------
on
(1 row)
postgres=# show enable_seqscan ;
enable_seqscan
----------------
on
(1 row)
postgres=# set enable_indexscan = 'off';
SET
postgres=# set enable_seqscan = 'off';
SET
postgres=#
postgres=# show enable_indexscan ;
enable_indexscan
------------------
off
(1 row)
postgres=# show enable_seqscan ;
enable_seqscan
----------------
off
(1 row)
postgres=# explain select * from pgbench_accounts where aid between 1 and 6500000;
QUERY PLAN
-----------------------------------------------------------------------------------------------
Bitmap Heap Scan on pgbench_accounts (cost=138389.90..441896.64 rows=6521899 width=97)
Recheck Cond: ((aid >= 1) AND (aid <= 6500000))
-> Bitmap Index Scan on pgbench_accounts_pkey (cost=0.00..136759.42 rows=6521899 width=0)
Index Cond: ((aid >= 1) AND (aid <= 6500000))
(4 rows)
postgres=# show enable_bitmapscan ;
enable_bitmapscan
-------------------
on
(1 row)
postgres=# set enable_bitmapscan = 'off';
SET
postgres=# show enable_bitmapscan ;
enable_bitmapscan
-------------------
off
(1 row)
postgres=# explain select * from pgbench_accounts where aid between 1 and 6500000;
QUERY PLAN
----------------------------------------------------------------------------------------------------------------
---------
Index Scan using pgbench_accounts_pkey on pgbench_accounts (cost=10000000000.43..10000308898.41 rows=6521899 w
idth=97)
Index Cond: ((aid >= 1) AND (aid <= 6500000))
(2 rows)
postgres=#
運用フェーズも見越して、pg_hint_plan などは事前に導入しておきましょう ![]()