From: Kyotaro Horiguchi Date: Thu, 18 Sep 2014 05:26:43 +0000 (+0900) Subject: Add new join method hint "NestLoop_NM" which means force nested loop X-Git-Tag: REL93_1_1_2~11 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=fd8affb6b71d00243c126e566d4ac7e34b13e8f3;p=pghintplan%2Fpg_hint_plan.git Add new join method hint "NestLoop_NM" which means force nested loop but inhibit materialize of the inner relation. --- diff --git a/doc/hint_list-ja.html b/doc/hint_list-ja.html index 70af266..059f560 100644 --- a/doc/hint_list-ja.html +++ b/doc/hint_list-ja.html @@ -54,9 +54,11 @@ PostgreSQL 9.2以降で動作します。 NoBitmapScan(テーブル) 指定したテーブルについて、Bitmap Scan以外でコストが最小となるスキャン方式を選択します。 -結合方式 +結合方式 NestLoop(テーブル テーブル[ テーブル...]) 指定したテーブル間の結合にNested Loopを選択します。 + NestLoop_NM(テーブル テーブル[ テーブル...]) + 指定したテーブル間の結合にNested Loopを選択しますがマテリアライズを禁止します。 HashJoin(テーブル テーブル[ テーブル...]) 指定したテーブル間の結合にHash Joinを選択します。 MergeJoin(テーブル テーブル[ テーブル...]) diff --git a/doc/pg_hint_plan-ja.html b/doc/pg_hint_plan-ja.html index 7660480..7249633 100644 --- a/doc/pg_hint_plan-ja.html +++ b/doc/pg_hint_plan-ja.html @@ -256,6 +256,12 @@ postgres-# ORDER BY a.aid;

あるオブジェクトの組み合わせでどのような順番で結合するかを指定できるヒント句のグループです。「Leading」のみを含みます。

結合順序を指定できるオブジェクトは結合方式と同じです。

先に結合して欲しいオブジェクトから順にオブジェクト名または別名を指定します。同じ問合せブロックのオブジェクトに対して複数の結合順序のヒント句を指定した場合は、最後に指定したヒント句が適用されます。

+

2つのオブジェクトの組を丸括弧で囲うと結合の内外を指定することができます。この指定はネストさせることができます。 +

+Leading((t5 (t1 t2)))
+
+は、t1とt2の結合をt1をアウタとして結合し、さらにそれとt5をt5をアウタとして結合します。 +

結合対象のテーブルが3つ以上ある場合、結合方式のヒント句を指定したとしてもコスト見積もりによっては対象のテーブルが直接結合されないことがあります。対象のテーブルが直接結合されない場合は、結合順序のヒント句を併せて指定します。

diff --git a/pg_hint_plan.c b/pg_hint_plan.c index 8e85100..27f70cf 100644 --- a/pg_hint_plan.c +++ b/pg_hint_plan.c @@ -81,6 +81,7 @@ PG_MODULE_MAGIC; #define HINT_INDEXONLYSCANREGEXP "IndexOnlyScanRegexp" #define HINT_NOINDEXONLYSCAN "NoIndexOnlyScan" #define HINT_NESTLOOP "NestLoop" +#define HINT_NESTLOOP_NM "NestLoop_NM" #define HINT_MERGEJOIN "MergeJoin" #define HINT_HASHJOIN "HashJoin" #define HINT_NONESTLOOP "NoNestLoop" @@ -114,13 +115,15 @@ enum { ENABLE_NESTLOOP = 0x01, ENABLE_MERGEJOIN = 0x02, - ENABLE_HASHJOIN = 0x04 + ENABLE_HASHJOIN = 0x04, + ENABLE_MATERIALIZE = 0x08 } JOIN_TYPE_BITS; #define ENABLE_ALL_SCAN (ENABLE_SEQSCAN | ENABLE_INDEXSCAN | \ ENABLE_BITMAPSCAN | ENABLE_TIDSCAN | \ ENABLE_INDEXONLYSCAN) -#define ENABLE_ALL_JOIN (ENABLE_NESTLOOP | ENABLE_MERGEJOIN | ENABLE_HASHJOIN) +#define ENABLE_ALL_JOIN (ENABLE_NESTLOOP | ENABLE_MERGEJOIN | ENABLE_HASHJOIN |\ + ENABLE_MATERIALIZE) #define DISABLE_ALL_SCAN 0 #define DISABLE_ALL_JOIN 0 @@ -141,6 +144,7 @@ typedef enum HintKeyword HINT_KEYWORD_INDEXONLYSCANREGEXP, HINT_KEYWORD_NOINDEXONLYSCAN, HINT_KEYWORD_NESTLOOP, + HINT_KEYWORD_NESTLOOP_NM, HINT_KEYWORD_MERGEJOIN, HINT_KEYWORD_HASHJOIN, HINT_KEYWORD_NONESTLOOP, @@ -242,6 +246,7 @@ typedef struct JoinMethodHint unsigned char enforce_mask; Relids joinrelids; Relids inner_joinrelids; + bool inhibit_materialize; } JoinMethodHint; /* join order hints */ @@ -491,6 +496,7 @@ static const HintParser parsers[] = { HINT_KEYWORD_INDEXONLYSCANREGEXP}, {HINT_NOINDEXONLYSCAN, ScanMethodHintCreate, HINT_KEYWORD_NOINDEXONLYSCAN}, {HINT_NESTLOOP, JoinMethodHintCreate, HINT_KEYWORD_NESTLOOP}, + {HINT_NESTLOOP_NM, JoinMethodHintCreate, HINT_KEYWORD_NESTLOOP_NM}, {HINT_MERGEJOIN, JoinMethodHintCreate, HINT_KEYWORD_MERGEJOIN}, {HINT_HASHJOIN, JoinMethodHintCreate, HINT_KEYWORD_HASHJOIN}, {HINT_NONESTLOOP, JoinMethodHintCreate, HINT_KEYWORD_NONESTLOOP}, @@ -671,6 +677,7 @@ JoinMethodHintCreate(const char *hint_str, const char *keyword, hint->enforce_mask = 0; hint->joinrelids = NULL; hint->inner_joinrelids = NULL; + hint->inhibit_materialize = false; return (Hint *) hint; } @@ -1889,9 +1896,12 @@ JoinMethodHintParse(JoinMethodHint *hint, HintState *hstate, Query *parse, switch (hint_keyword) { - case HINT_KEYWORD_NESTLOOP: + case HINT_KEYWORD_NESTLOOP_NM: hint->enforce_mask = ENABLE_NESTLOOP; break; + case HINT_KEYWORD_NESTLOOP: + hint->enforce_mask |= (ENABLE_NESTLOOP | ENABLE_MATERIALIZE); + break; case HINT_KEYWORD_MERGEJOIN: hint->enforce_mask = ENABLE_MERGEJOIN; break; @@ -1899,13 +1909,13 @@ JoinMethodHintParse(JoinMethodHint *hint, HintState *hstate, Query *parse, hint->enforce_mask = ENABLE_HASHJOIN; break; case HINT_KEYWORD_NONESTLOOP: - hint->enforce_mask = ENABLE_ALL_JOIN ^ ENABLE_NESTLOOP; + hint->enforce_mask = (ENABLE_ALL_JOIN ^ ENABLE_NESTLOOP); break; case HINT_KEYWORD_NOMERGEJOIN: - hint->enforce_mask = ENABLE_ALL_JOIN ^ ENABLE_MERGEJOIN; + hint->enforce_mask = (ENABLE_ALL_JOIN ^ ENABLE_MERGEJOIN); break; case HINT_KEYWORD_NOHASHJOIN: - hint->enforce_mask = ENABLE_ALL_JOIN ^ ENABLE_HASHJOIN; + hint->enforce_mask = (ENABLE_ALL_JOIN ^ ENABLE_HASHJOIN); break; default: hint_ereport(str, ("Unrecognized hint keyword \"%s\".", keyword)); @@ -2223,6 +2233,7 @@ set_join_config_options(unsigned char enforce_mask, GucContext context) SET_CONFIG_OPTION("enable_nestloop", ENABLE_NESTLOOP); SET_CONFIG_OPTION("enable_mergejoin", ENABLE_MERGEJOIN); SET_CONFIG_OPTION("enable_hashjoin", ENABLE_HASHJOIN); + SET_CONFIG_OPTION("enable_material", ENABLE_MATERIALIZE); } /* @@ -2480,6 +2491,8 @@ pg_hint_plan_planner(Query *parse, int cursorOptions, ParamListInfo boundParams) current_hint->init_join_mask |= ENABLE_MERGEJOIN; if (enable_hashjoin) current_hint->init_join_mask |= ENABLE_HASHJOIN; + if (enable_material) + current_hint->init_join_mask |= ENABLE_MATERIALIZE; /* * Use PG_TRY mechanism to recover GUC parameters and current_hint to the