次のヒントは、オプティマイザがリレーションにアクセスして結果セットを作成する方法を決定するものです。
ヒント | 説明 |
---|---|
FULL(table) | テーブルに対してフルシーケンシャルスキャンを実行します。 |
INDEX(table [ index ] [...]) | リレーションにアクセスするためにテーブルのインデックスを使用します。 |
NO_INDEX(table [ index ] [...]) | リレーションにアクセスするためにテーブルのインデックスを使用しません。 |
さらに、このテーブルにある ALL_ROWS、FIRST_ROWS、および FIRST_ROWS(n) のヒントが使用できます。
例
サンプルアプリケーションには、オプティマイザのヒントの効果を説明するのに十分なデータがありません。 したがって、本ページの残りの例では、pgbench アプリケーションによって作成された銀行データベースを使用しています。 このアプリケーションは、Oracle と互換性のある PolarDB データベースの bin サブディレクトリにあります。
次の例は、bank という名前のデータベースを作成する方法を示しています。 pgbench_accounts、pgbench_branches、pgbench_tellers、pgbench_history を含むテーブルがデータベースに追加されます。 -s 20 オプションで、倍率を 20 に指定します。 この係数により、20 個の支店を作成できます。 各支店には 100,000 個の銀行口座があります。 したがって、pgbench_accounts テーブルに合計 2,000,000 行生成され、pgbench_branches テーブルに 20 行生成されます。 各支店には 10 人の出納係が割り当てられています。 結果として、pgbench_tellers テーブルに合計 200 行生成されます。
次の例は、銀行データベースで pgbench アプリケーションを初期化する方法を示しています。
createdb -U enterprisedb bank
CREATE DATABASE
pgbench -i -s 20 -U enterprisedb bank
NOTICE: table "pgbench_history" does not exist, skipping
NOTICE: table "pgbench_tellers" does not exist, skipping
NOTICE: table "pgbench_accounts" does not exist, skipping
NOTICE: table "pgbench_branches" does not exist, skipping
creating tables...
100000 of 2000000 tuples (5%) done (elapsed 0.11 s, remaining 2.10 s)
200000 of 2000000 tuples (10%) done (elapsed 0.22 s, remaining 1.98 s)
300000 of 2000000 tuples (15%) done (elapsed 0.33 s, remaining 1.84 s)
400000 of 2000000 tuples (20%) done (elapsed 0.42 s, remaining 1.67 s)
500000 of 2000000 tuples (25%) done (elapsed 0.52 s, remaining 1.57 s)
600000 of 2000000 tuples (30%) done (elapsed 0.62 s, remaining 1.45 s)
700000 of 2000000 tuples (35%) done (elapsed 0.73 s, remaining 1.35 s)
800000 of 2000000 tuples (40%) done (elapsed 0.87 s, remaining 1.31 s)
900000 of 2000000 tuples (45%) done (elapsed 0.98 s, remaining 1.19 s)
1000000 of 2000000 tuples (50%) done (elapsed 1.09 s, remaining 1.09 s)
1100000 of 2000000 tuples (55%) done (elapsed 1.22 s, remaining 1.00 s)
1200000 of 2000000 tuples (60%) done (elapsed 1.36 s, remaining 0.91 s)
1300000 of 2000000 tuples (65%) done (elapsed 1.51 s, remaining 0.82 s)
1400000 of 2000000 tuples (70%) done (elapsed 1.65 s, remaining 0.71 s)
1500000 of 2000000 tuples (75%) done (elapsed 1.78 s, remaining 0.59 s)
1600000 of 2000000 tuples (80%) done (elapsed 1.93 s, remaining 0.48 s)
1700000 of 2000000 tuples (85%) done (elapsed 2.10 s, remaining 0.37 s)
1800000 of 2000000 tuples (90%) done (elapsed 2.23 s, remaining 0.25 s)
1900000 of 2000000 tuples (95%) done (elapsed 2.37 s, remaining 0.12 s)
2000000 of 2000000 tuples (100%) done (elapsed 2.48 s, remaining 0.00 s)
vacuum...
set primary keys...
done.
合計 500,000 個のトランザクションが処理されます。 したがって、pgbench_history テーブルに 500,000 行追加されます。
pgbench -U enterprisedb -t 500000 bank
starting vacuum...end.
transaction type: <builtin: TPC-B (sort of)>
scaling factor: 20
query mode: simple
number of clients: 1
number of threads: 1
number of transactions per client: 500000
number of transactions actually processed: 500000/500000
latency average: 0.000 ms
tps = 1464.338375 (including connections establishing)
tps = 1464.350357 (excluding connections establishing)
次の例は、テーブル定義を示しています。
\d pgbench_accounts
Table "public.pgbench_accounts"
Column | Type | Modifiers
----------+---------------+-----------
aid | integer | not null
bid | integer |
abalance | integer |
filler | character(84) |
Indexes:
"pgbench_accounts_pkey" PRIMARY KEY, btree (aid)
\d pgbench_branches
Table "public.pgbench_branches"
Column | Type | Modifiers
----------+---------------+-----------
bid | integer | not null
bbalance | integer |
filler | character(88) |
Indexes:
"pgbench_branches_pkey" PRIMARY KEY, btree (bid)
\d pgbench_tellers
Table "public.pgbench_tellers"
Column | Type | Modifiers
----------+---------------+-----------
tid | integer | not null
bid | integer |
tbalance | integer |
filler | character(84) |
Indexes:
"pgbench_tellers_pkey" PRIMARY KEY, btree (tid)
\d pgbench_history
Table "public.pgbench_history"
Column | Type | Modifiers
--------+-----------------------------+-----------
tid | integer |
bid | integer |
aid | integer |
delta | integer |
mtime | timestamp without time zone |
filler | character(22) |
EXPLAIN 文は、クエリプランナーが選択したプランを示しています。 次の例では、aid が主キー列です。 インデックス付き検索は、pgbench_accounts_pkey インデックスで使用されます。
EXPLAIN SELECT * FROM pgbench_accounts WHERE aid = 100;
QUERY PLAN
-----------------------------------------------------------------------------------------------
Index Scan using pgbench_accounts_pkey on pgbench_accounts (cost=0.43..8.45 rows=1 width=97)
Index Cond: (aid = 100)
(2 rows)
次の例では、FULL ヒントを使用して強制的にフルシーケンシャルスキャンを実行します。 インデックスは使用しません。
EXPLAIN SELECT /*+ FULL(pgbench_accounts) */ * FROM pgbench_accounts WHERE aid = 100;
QUERY PLAN
---------------------------------------------------------------------
Seq Scan on pgbench_accounts (cost=0.00..58781.69 rows=1 width=97)
Filter: (aid = 100)
(2 rows)
次の例では、NO_INDEX ヒントで、強制的に並列シーケンシャルスキャンを実行します。 インデックスは使用しません。
EXPLAIN SELECT /*+ NO_INDEX(pgbench_accounts pgbench_accounts_pkey) */ * FROM pgbench_accounts WHERE aid = 100;
QUERY PLAN
------------------------------------------------------------------------------------
Gather (cost=1000.00..45094.80 rows=1 width=97)
Workers Planned: 2
-> Parallel Seq Scan on pgbench_accounts (cost=0.00..44094.70 rows=1 width=97)
Filter: (aid = 100)
(4 rows)
前の例の EXPLAIN 文に加えて、trace_hints 設定パラメーターを設定すると、プランナーがヒントを使用しているかどうかについて、さらに詳細な情報を取得できます。
SET trace_hints TO on;
次の例では、NO_INDEX ヒントがある SELECT 文を繰り返して、trace_hints 設定パラメーターを設定後に生成される追加情報を表示します。
EXPLAIN SELECT /*+ NO_INDEX(pgbench_accounts pgbench_accounts_pkey) */ * FROM pgbench_accounts WHERE aid = 100;
INFO: [HINTS] Index Scan of [pgbench_accounts].[pgbench_accounts_pkey] rejected due to NO_INDEX hint.
QUERY PLAN
------------------------------------------------------------------------------------
Gather (cost=1000.00..45094.80 rows=1 width=97)
Workers Planned: 2
-> Parallel Seq Scan on pgbench_accounts (cost=0.00..44094.70 rows=1 width=97)
Filter: (aid = 100)
(4 rows)
ヒントが無視されると、INFO: [HINTS] の行は表示されません。 これは、ヒントに構文エラーまたはスペルエラーが存在することを表している可能性があります。 次の例は、インデックス名のスペルが間違っていることを示しています。
EXPLAIN SELECT /*+ NO_INDEX(pgbench_accounts pgbench_accounts_xxx) */ * FROM pgbench_accounts WHERE aid = 100;
QUERY PLAN
-----------------------------------------------------------------------------------------------
Index Scan using pgbench_accounts_pkey on pgbench_accounts (cost=0.43..8.45 rows=1 width=97)
Index Cond: (aid = 100)
(2 rows)