OSDN Git Service

Fix versions and copyright year of doc
[pghintplan/pg_hint_plan.git] / doc / pg_hint_plan-ja.html
old mode 100644 (file)
new mode 100755 (executable)
index 407dffc..783600f
@@ -1,5 +1,5 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD html 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
-<html>
+<html lang="ja">
 <head>
 <title>pg_hint_plan</title>
 <!-- Uncoment after the tool has been hosted somewhere.
@@ -10,7 +10,7 @@
 </head>
 
 <body>
-<h1 id="pg_hint_plan">pg_hint_plan 1.1.0</h1>
+<h1 id="pg_hint_plan">pg_hint_plan 1.6</h1>
 <div class="navigation">
   <a href="pg_hint_plan-ja.html">pg_hint_plan</a>
 </div>
@@ -33,7 +33,7 @@
 <p>pg_hint_plan -- 実行計画を示すヒントをクエリに指定することで、SQL文やGUCパラメータを変えずに実行計画を制御します。</p>
 
 <h2 id="synopsis">概要</h2>
-<p>PostgreSQLã\81¯ã\82³ã\82¹ã\83\88ã\83\99ã\83¼ã\82¹ã\82ªã\83\97ã\83\86ã\82£ã\83\9eã\82¤ã\82¶ã\82\92æ\8e¡ç\94¨ã\81\97ã\81¦ã\81\8aã\82\8aã\80\81SQLæ\96\87ã\81¨çµ±è¨\88æ\83\85å ±ã\82\92å\85\83ã\81«å\8f¯è\83½ã\81ªå®\9fè¡\8cè¨\88ç\94»ã\81®ã\82³ã\82¹ã\83\88ã\82\92è¦\8bç©\8dã\82\82ã\82\8aã\80\81æ\9c\80ã\82\82ã\82³ã\82¹ã\83\88ã\81®ä½\8eã\81\84å®\9fè¡\8cè¨\88ç\94»ã\82\92é\81¸æ\8a\9eã\81\97ã\81¾ã\81\99ã\80\82ã\82ªã\83\97ã\83\86ã\82£ã\83\9eã\82¤ã\82¶ã\81¯å\8f¯è\83½ã\81ªé\99\90ã\82\8aã\82\88ã\81\84å®\9fè¡\8cè¨\88ç\94»ã\82\92ä½\9cæ\88\90ã\81\97ã\82\88ã\81\86ã\81¨ã\81\97ã\81¾ã\81\99ã\81\8cã\80\81カラム間の相関関係などは考慮しないため、複雑なクエリでは常に最適なプランを選択するとは限りません。</p>
+<p>PostgreSQLã\81®ã\83\97ã\83©ã\83³ã\83\8aã\81¯ã\81¯ã\82³ã\82¹ã\83\88ã\83\99ã\83¼ã\82¹ã\81§ã\81®ã\82ªã\83\97ã\83\86ã\82£ã\83\9eã\82¤ã\82ºã\82\92è¡\8cã\81ªã\81£ã\81¦ã\81\8aã\82\8aã\80\81SQLæ\96\87ã\81¨çµ±è¨\88æ\83\85å ±ã\82\92å\85\83ã\81«å\8f¯è\83½ã\81ªå®\9fè¡\8cè¨\88ç\94»ã\81®ã\82³ã\82¹ã\83\88ã\82\92è¦\8bç©\8dã\82\82ã\82\8aã\80\81æ\9c\80ã\82\82ã\82³ã\82¹ã\83\88ã\81®ä½\8eã\81\84å®\9fè¡\8cè¨\88ç\94»ã\82\92é\81¸æ\8a\9eã\81\97ã\81¾ã\81\99ã\80\82ã\83\97ã\83©ã\83³ã\83\8aã\81¯å\8f¯è\83½ã\81ªé\99\90ã\82\8aã\82\88ã\81\84å®\9fè¡\8cè¨\88ç\94»ã\82\92ä½\9cæ\88\90ã\81\97ã\82\88ã\81\86ã\81¨ã\81\97ã\81¾ã\81\99ã\81\8cã\80\81ä¾\8bã\81\88ã\81°カラム間の相関関係などは考慮しないため、複雑なクエリでは常に最適なプランを選択するとは限りません。</p>
 <p>pg_hint_planを用いると、ヒントでスキャン方式や結合方式を指定することで、SQL文やGUCパラメータを変更することなく実行計画を制御することができます。</p>
 
 <h2 id="description">機能説明</h2>
 <p>ヒント用コメントと通常のコメントを区別するために、ヒント用のブロックコメントは「<span class="bold">/*+</span>」で始めます。ヒントの対象は、カッコ内にオブジェクト名または別名で指定します。オブジェクト名は、スペース、タブ、または改行のいずれかで区切って指定します。</p>
 <p>以下の例では、HashJoinとSeqScanヒント句により、pgbench_accountsテーブルに対するSeq Scanの結果をHash Joinする実行計画が選択されています。なおかつ、Setヒント句によりこのクエリの実行計画を作成する間だけrandom_page_costが2.0に変更されています。</p>
 <pre>
-postgres=# EXPLAIN (VERBOSE, COSTS)
-postgres-# /*+
-postgres*#     SeqScan(a)
-postgres*#     HashJoin(a b)
-postgres*#     Set(random_page_cost 2.0)
-postgres*#  */
-postgres-# SELECT *
-postgres-#   FROM pgbench_accounts a
-postgres-#   JOIN pgbench_branches b
-postgres-#     ON a.bid = b.bid
-postgres-#  ORDER BY a.aid
-postgres-#  LIMIT 10;
+<span class="strong">postgres=#</span> EXPLAIN (VERBOSE, COSTS)
+<span class="strong">postgres-# /*+</span>
+<span class="strong">postgres*#     SeqScan(a)</span>
+<span class="strong">postgres*#     HashJoin(a b)</span>
+<span class="strong">postgres*#     Set(random_page_cost 2.0)</span>
+<span class="strong">postgres*#  */</span>
+<span class="strong">postgres-#</span> SELECT *
+<span class="strong">postgres-#</span>   FROM pgbench_accounts a
+<span class="strong">postgres-#</span>   JOIN pgbench_branches b
+<span class="strong">postgres-#</span>     ON a.bid = b.bid
+<span class="strong">postgres-#</span>  ORDER BY a.aid
+<span class="strong">postgres-#</span>  LIMIT 10;
                                              QUERY PLAN
 ----------------------------------------------------------------------------------------------------
  Limit  (cost=6176.99..6177.01 rows=10 width=461)
@@ -101,7 +101,7 @@ postgres=#
 
 <h4 id="hint-table">テーブルでの指定</h4>
 <p>指定したいヒントを、実行計画を制御したいクエリと併せてヒント用のテーブルに登録します。</p>
-<p>デフォルトでは無効なので、テーブルで指定したヒントは適用されません。そのため、ヒントをテーブルで指定する場合は、<a href="#hint-GUC">pg_hint_planのGUCパラメータ</a>pg_hint_plan.enable_hint_tableの設定を変更します。</p>
+<p>デフォルトでは無効なので、テーブルで指定したヒントは適用されません。そのため、ヒントをテーブルで指定する場合は、<a href="#hint-GUC">pg_hint_planのGUCパラメータ</a>pg_hint_plan.enable_hint_tableの設定を変更します。この機能を利用する場合にはcompute_query_idが"auto"または"on"である必要があります。</p>
 <p>ヒント用のテーブルは「<span class="bold">hint_plan.hints</span>」です。hint_plan.hintsテーブルには、以下の情報を登録します。</p>
 <table>
 <thead>
@@ -116,7 +116,7 @@ postgres=#
 <tr><td>application_name</td>
   <td>ヒント適用対象のアプリケーション名を指定します。下記の例では「psql」から実行されたクエリのみがヒント適用対象となります。全てのアプリケーションにヒントを適用したいときは、空文字列を登録します。アプリケーション名は、セッションの「application_name」GUCパラメータと等しいか判断します。</td></tr>
 <tr><td>hints</td>
-  <td>ヒントを指定します。ヒント以外のもの(SQLコメントなど)を含めないでください。</td></tr>
+  <td>ヒントを指定します。SQLコメント記号を除いた内容のみを登録します。</td></tr>
 </tbody>
 </table>
 <p>ヒントの登録情報を変更する場合は、変更したい登録情報のidを指定して登録情報を更新してください。</br>
@@ -124,37 +124,37 @@ postgres=#
 <p>以下の例では、ヒントの登録、ヒント登録情報の変更、ヒントの解除の順に、クエリの実行結果を示しています。
 </p>
 <pre>
-postgres=# INSERT INTO hint_plan.hints(norm_query_string, application_name, hints)
-postgres-#     VALUES (
-postgres(#         'EXPLAIN (COSTS false) SELECT * FROM t1 WHERE t1.id = ?;',
-postgres(#         '',
-postgres(#         'SeqScan(t1)'
-postgres(#     );
+<span class="strong">postgres=#</span> INSERT INTO hint_plan.hints(norm_query_string, application_name, hints)
+<span class="strong">postgres-#</span>     VALUES (
+<span class="strong">postgres(#</span>         'EXPLAIN (COSTS false) SELECT * FROM t1 WHERE t1.id = ?;',
+<span class="strong">postgres(#</span>         '',
+<span class="strong">postgres(#</span>         'SeqScan(t1)'
+<span class="strong">postgres(#</span>     );
 INSERT 0 1
-postgres=# UPDATE hint_plan.hints
-postgres-#    SET hints = 'IndexScan(t1)'
-postgres-#  WHERE id = 1;
+<span class="strong">postgres=#</span> UPDATE hint_plan.hints
+<span class="strong">postgres-#</span>    SET hints = 'IndexScan(t1)'
+<span class="strong">postgres-#</span>  WHERE id = 1;
 UPDATE 1
-postgres=# DELETE FROM hint_plan.hints
-postgres-#  WHERE id = 1;
+<span class="strong">postgres=#</span> DELETE FROM hint_plan.hints
+<span class="strong">postgres-#</span>  WHERE id = 1;
 DELETE 1
-postgres=#
+<span class="strong">postgres=#</span>
 </pre>
 <p>なお、ヒントの登録や変更や解除はスーパーユーザでのみ可能です。一般ユーザでヒントの登録や変更や解除を実施したい場合は、スーパーユーザから一般ユーザにhint_plan.hintsテーブルの各権限を付与してください。</p>
 <p>以下の例では、hint_plan.hintsテーブルに対してINSERT権限を持たない一般ユーザがヒントの登録を実施しようとしたときの結果を示しています。</p>
 <pre>
-postgres=> INSERT INTO hint_plan.hints(norm_query_string, application_name, hints)
-postgres->     VALUES (
-postgres(>         'EXPLAIN (COSTS false) SELECT * FROM t1 WHERE t1.id = ?;',
-postgres(>         '',
-postgres(>         'SeqScan(t1)'
-postgres(>     );
+<span class="strong">postgres=></span> INSERT INTO hint_plan.hints(norm_query_string, application_name, hints)
+<span class="strong">postgres-></span>     VALUES (
+<span class="strong">postgres(></span>         'EXPLAIN (COSTS false) SELECT * FROM t1 WHERE t1.id = ?;',
+<span class="strong">postgres(></span>         '',
+<span class="strong">postgres(></span>         'SeqScan(t1)'
+<span class="strong">postgres(></span>     );
 ERROR:  permission denied for relation hints
-postgres=>
+<span class="strong">postgres=></span>
 </pre>
 <p>以下の例では、テーブルに登録した「コメントでの指定」の例と同じヒントと、登録したクエリの実行結果を示しています。</p>
 <pre>
-postgres=# SELECT * FROM hint_plan.hints;
+<span class="strong">postgres=#</span> SELECT * FROM hint_plan.hints;
  id |     norm_query_string      | application_name |                      hints
 ----+----------------------------+------------------+--------------------------------------------------
   1 | EXPLAIN (VERBOSE, COSTS)  +| psql             | SeqScan(a)HashJoin(a b)Set(random_page_cost 2.0)
@@ -167,14 +167,14 @@ postgres=# SELECT * FROM hint_plan.hints;
     |                            |                  |
 ...
 
-postgres=# SET pg_hint_plan.enable_hint_table TO on;
-postgres=# EXPLAIN (VERBOSE, COSTS)
-postgres-# SELECT *
-postgres-#   FROM pgbench_accounts a
-postgres-#   JOIN pgbench_branches b
-postgres-#     ON a.bid = b.bid
-postgres-#  ORDER BY a.aid
-postgres-#  LIMIT 10;
+<span class="strong">postgres=#</span> SET pg_hint_plan.enable_hint_table TO on;
+<span class="strong">postgres=#</span> EXPLAIN (VERBOSE, COSTS)
+<span class="strong">postgres-#</span> SELECT *
+<span class="strong">postgres-#</span>   FROM pgbench_accounts a
+<span class="strong">postgres-#</span>   JOIN pgbench_branches b
+<span class="strong">postgres-#</span>     ON a.bid = b.bid
+<span class="strong">postgres-#</span>  ORDER BY a.aid
+<span class="strong">postgres-#</span>  LIMIT 10;
                                              QUERY PLAN
 ----------------------------------------------------------------------------------------------------
  Limit  (cost=6176.99..6177.01 rows=10 width=461)
@@ -240,7 +240,7 @@ postgres-#  ORDER BY a.aid;
 </div>
 
 <h3 id="hint-group">ヒント句のグループ</h3>
-<p>pg_hint_planで使えるヒント句の種類は、スキャン方式と結合方式、結合順序、GUCパラメータの4グループです。各グループの具体的なヒント句は、<a href="hint_list-ja.html">ヒント句一覧</a>を参照してください。</p>
+<p>pg_hint_planで使えるヒント句の種類は、スキャン方式と結合方式、結合順序、見積もり件数補正、並列実行の設定、GUCパラメータの6グループです。各グループの具体的なヒント句は、<a href="hint_list-ja.html">ヒント句一覧</a>を参照してください。</p>
 
 <h4>スキャン方式</h4>
 <p>あるオブジェクトでどのスキャン方式を選択するかを指定できるヒント句のグループです。「SeqScan」や「IndexScan」などを含みます。</p>
@@ -257,21 +257,85 @@ postgres-#  ORDER BY a.aid;
 <p>結合順序を指定できるオブジェクトは結合方式と同じです。</p>
 <p>先に結合して欲しいオブジェクトから順にオブジェクト名または別名を指定します。同じ問合せブロックのオブジェクトに対して複数の結合順序のヒント句を指定した場合は、最後に指定したヒント句が適用されます。 </p>
 <div class="tips">
-<span class="strong"></span>
 <p>結合対象のテーブルが3つ以上ある場合、結合方式のヒント句を指定したとしてもコスト見積もりによっては対象のテーブルが直接結合されないことがあります。対象のテーブルが直接結合されない場合は、結合順序のヒント句を併せて指定します。</p>
 <p>以下の例では、table1とtable2を直接結合する場合はNested Loopを、table1とtable2とtable3を結合する場合はMerge Joinを指定しています。また、コスト見積もりによってはtable1とtable2が直接結合されない場合を避けるため、table1とtable2を結合してからtable3を結合するようにLeadingヒント句を併用しています。</p>
 <pre>
-postgres=# /*+
-postgres*#     NestLoop(t1 t2)
-postgres*#     MergeJoin(t1 t2 t3)
-postgres*#     Leading(t1 t2 t3)
-postgres*#  */
-postgres-# SELECT * FROM table1 t1
-postgres-#     JOIN table table2 t2 ON (t1.key = t2.key)
-postgres-#     JOIN table table3 t3 ON (t2.key = t3.key);
+<span class="strong">postgres=# /*+</span>
+<span class="strong">postgres*#     NestLoop(t1 t2)</span>
+<span class="strong">postgres*#     MergeJoin(t1 t2 t3)</span>
+<span class="strong">postgres*#     Leading(t1 t2 t3)</span>
+<span class="strong">postgres*#  */</span>
+<span class="strong">postgres-#</span> SELECT * FROM table1 t1
+<span class="strong">postgres-#</span>     JOIN table table2 t2 ON (t1.key = t2.key)
+<span class="strong">postgres-#</span>     JOIN table table3 t3 ON (t2.key = t3.key);
 ...
 </pre>
 </div>
+<h4>結合方向</h4>
+<p>上記の結合順序の指定を行なった際にはプランナの都合により結合方向(外部表/内部表もしくは駆動表/被駆動表の別)が期待とは異なるものになる場合があります。このような状況に対して結合方向を固定したい場合はもうひとつの書式を使う必要があります。</p>
+<pre>
+<span class="strong">postgres=# /*+ Leading((t1 (t2 t3))) */</span> SELECT...
+</pre>
+<p>この書式では2つの要素を丸括弧で囲ったものがネストする形になっており、一つの括弧内では1つ目の要素が外部/駆動表、2番めの要素が内部/被駆動表として結合されます。</p>
+<h4>結合の挙動制御</h4>
+<p>あるオブジェクトの組み合わせ最上位結合の挙動を制御するヒント句のグループです。「Memoize」のみを含みます。</p>
+<p>Memoizeは最上位結合のインナープランの出力結果をキャッシングして高速化を試みる挙動を制御します。</p>
+<p>以下の例では、テーブルaとテーブルbの結合のインナー側(この例ではa側)のMemoizeを禁止します。</p>
+
+<pre>
+postgres=# /*+ NoMemoize(a b) */
+EXPLAIN SELECT * FROM a, b WHERE a.val = b.val;
+                             QUERY PLAN                             
+--------------------------------------------------------------------
+ Hash Join  (cost=270.00..1412.50 rows=100000 width=16)
+   Hash Cond: (b.val = a.val)
+   ->  Seq Scan on b  (cost=0.00..15.00 rows=1000 width=8)
+   ->  Hash  (cost=145.00..145.00 rows=10000 width=8)
+         ->  Seq Scan on a  (cost=0.00..145.00 rows=10000 width=8)
+(5 行)
+</pre>
+
+<h4>見積もり件数補正</h4>
+<p>あるオブジェクトの結合結果の件数を補正できるヒント句のグループです。「Rows」のみを含みます。</p>
+<p>見積もり件数補正対象として指定できるオブジェクトは結合方式と同じです。補正できるのは結合結果の見積もり件数だけで、スキャンの見積もり件数を補正することはできません。</p>
+<p>以下の例では、テーブルaとテーブルbの結合結果の件数を、ヒント句で指定した値に補正しています。</p>
+<pre>
+<span class="strong">postgres=# /*+ Rows(a b #10) */</span>
+<span class="strong">postgres-#</span> EXPLAIN SELECT *
+<span class="strong">postgres-#</span>    FROM pgbench_branches b
+<span class="strong">postgres-#</span>    JOIN pgbench_accounts a ON b.bid = a.bid
+<span class="strong">postgres-#</span>   WHERE aid &lt; 20
+<span class="strong">postgres-#</span>   ORDER BY a.aid;
+                                               QUERY PLAN
+--------------------------------------------------------------------------------------------------------
+ Nested Loop  (cost=0.29..9.92 rows=<span class="strong">10</span> width=461)
+   Join Filter: (b.bid = a.bid)
+   ->  Index Scan using pgbench_accounts_pkey on pgbench_accounts a  (cost=0.29. .8.62 rows=19 width=97)
+         Index Cond: (aid &lt; 20)
+   ->  Materialize  (cost=0.00..1.01 rows=1 width=364)
+         ->  Seq Scan on pgbench_branches b  (cost=0.00..1.01 rows=1 width=364)
+(6 行)
+</pre>
+
+<h4>並列実行の指定</h4>
+<p>スキャンの並列実行の方法を指定します。最初のパラメータは対象とするオブジェクトの指定で、2番目に指定する数だけ並列処理ワーカを起動するように指定します。
+<p>3番目のパラメータは強制の程度を指定します。 "soft" は max_parallel_workers_per_gather のみを変更して適用はプランナに任せます。"hard" は他のプランナ変数も変更するなどしてワーカ数を強制します。</p>
+<p>以下の例では、テーブル c1 とテーブル c2 の結合で各々異なるワーカ数を強制します。</p>
+<pre>
+<span class="strong">postgres=#</span> explain <span class="strong">/*+ Parallel(c1 3 hard) Parallel(c2 5 hard) */</span>
+                  select c2.a from c1 join c2 on (c1.a = c2.a);
+                                  QUERY PLAN                                   
+-------------------------------------------------------------------------------
+ Hash Join  (cost=2.86..11406.38 rows=101 width=4)
+   Hash Cond: (c1.a = c2.a)
+   ->  Gather  (cost=0.00..7652.13 rows=1000101 width=4)
+         <span class="strong">Workers Planned: 3</span>
+         ->  Parallel Seq Scan on <span class="strong">c1</span>  (cost=0.00..7652.13 rows=322613 width=4)
+   ->  Hash  (cost=1.59..1.59 rows=101 width=4)
+         ->  Gather  (cost=0.00..1.59 rows=101 width=4)
+               <span class="strong">Workers Planned: 5</span>
+               ->  Parallel Seq Scan on <span class="strong">c2</span>  (cost=0.00..1.59 rows=59 width=4)
+</pre>
 
 <h4>GUCパラメータ</h4>
 <p>そのクエリの実行計画を作成している間だけGUCパラメータを変更できるヒント句のグループです。「Set」のみを含みます。</p>
@@ -298,28 +362,15 @@ postgres-#     JOIN table table3 t3 ON (t2.key = t3.key);
   <td>pg_hint_planの機能を有効または無効にします。</td><td>on</td></tr>
 <tr><td>pg_hint_plan.enable_hint_table</td>
   <td>ヒントをテーブルで指定する機能を有効または無効にします。</td><td>off</td></tr>
-<tr><td>pg_hint_plan.debug_print</td>
-  <td>指定したヒントが実行計画生成にどのように影響したかを出力します。メッセージはLOGメッセージレベルで出力されますので、デフォルトではサーバログに出力され、クライアントには渡されません。</td><td>off</td></tr>
 <tr><td>pg_hint_plan.parse_messages</td>
-  <td>指定したヒントを解釈できなかった場合に、どのメッセージ階層でログを出力するかを指定します。有効な値は、debug5、debug4、debug3、debug2、debug1、log、info、notice、warning、またはerrorです。fatalとpanicは指定できません。</td><td>info</td></tr>
+  <td>指定したヒントを解釈できなかった場合のログメッセージのレベルを指定します。有効な値は、debug5、debug4、debug3、debug2、debug1、log、info、notice、warning、またはerrorです。</td><td>INFO</td></tr>
+<tr><td>pg_hint_plan.debug_print</td>
+  <td>動作状況を示すログメッセージの出力を制御します。指定可能な値は off, on, verbose, detailed です。</td><td>off</td></tr>
+<tr><td>pg_hint_plan.message_level</td>
+  <td>動作ログメッセージのログレベルを指定します。有効な値は、debug5、debug4、debug3、debug2、debug1、log、info、notice、warning、またはerrorです。</td><td>LOG</td></tr>
 
 </tbody>
 </table>
-<p>
-PostgreSQL 9.1の環境でこれらのパラメータをpostgresql.confファイルで設定するには、<a href="http://www.postgresql.jp/document/9.1/html/runtime-config-custom.html#GUC-CUSTOM-VARIABLE-CLASSES">custom_variable_classes</a>にpg_hint_planを加える必要があります。
-典型的な使用例は以下のようになります。
-</p>
-<pre>
-# postgresql.conf
-shared_preload_libraries = 'pg_hint_plan'
-
-custom_variable_classes = 'pg_hint_plan'    # 9.2以降は廃止されたため記述不要
-pg_hint_plan.parse_messages = 'debug2'
-</pre>
-<p>
-PostgreSQL 9.2以降ではcustom_variable_classesは廃止されているため、pg_hint_planのGUCパラメータを標準のGUCパラメータと同様に記述することができます。
-</p>
-
 <h2 id="install">インストール</h2>
 <p>pg_hint_planのインストール方法について説明します。</p>
 
@@ -374,11 +425,10 @@ $ psql -d <i>dbname</i> -c "DROP SCHEMA hint_plan"
 </pre>
 </ol>
 
-<h2 id="restrictions">使用上の注意と制約</h2>
-<p>pg_hint_planを使用する際には、以下の注意と制約があります。</p>
-<h3>ヒントの指定方法</h3>
+<h2 id="restrictions">ヒントの指定に関する詳細</h2>
+<p>以下にいくつかのトピックに関してヒントの動作について説明します。</p>
 <dl>
-<dt>コメント指定でのヒント記述位置</dt>
+<dt>コメント指定でのヒント記述位置と文法</dt>
 <dd>ヒントはクエリの先頭または途中に記述できます。ただし、ヒントをクエリの途中に記述する場合、ヒント用のブロックコメントより前に以下の文字<span class="strong">以外</span>が含まれると、「/*+」で始まるコメントでもヒントと見なされず無視されます。
 <ul>
 <li>空白文字(半角スペース、水平/垂直タブ、改行、フォームフィード、復帰)</li>
@@ -437,7 +487,19 @@ postgres-#   ORDER BY a.aid;
 postgres=# </pre>
 </dd>
 <dt>PL/pgSQL中の個別のクエリに対するヒント</dt>
-<dd>ヒントは、PL/pgSQLブロック中のPERFORM文を除いた各クエリにも指定できます。ただし、コメントで指定する場合は、SELECTなどのSQLキーワードより後に指定してください。
+<dd>ヒントは、PL/pgSQLブロック中の各クエリにも指定できます。ただし、以下のような制約があります。
+<ul>
+<li>指定したヒントが適用されるSQLは以下の通りです。他のSQLにヒントを指定しても適用されません。
+<ul>
+<li>1行の結果を返す問い合わせ文(SELECT/INSERT/UPDATE/DELETE)</li>
+<li>複数行の結果を返す問い合わせ文(RETURN QUERY)</li>
+<li>動的SQL文(EXECUTE)</li>
+<li>カーソルを開く文(OPEN)</li>
+<li>問い合わせの結果を用いる繰り返し文(FOR)</li>
+</ul>
+</li>
+<li>ヒントをコメントで指定する場合は、SELECTなどのSQLキーワードより後に指定してください。ただし、動的SQL文にヒントをコメントで指定しても、そのヒントは適用されません。</li>
+</ul>
 <p>以下の例では、一つ目のクエリにNoIndexScanを、二つ目のクエリにSeqScanをそれぞれ指定しています。</p>
 <pre>
 postgres=# CREATE FUNCTION hints_func(integer) RETURNS integer AS $$
@@ -445,16 +507,18 @@ postgres$# DECLARE
 postgres$#     id  integer;
 postgres$#     cnt integer;
 postgres$# BEGIN
-postgres$#     SELECT /*+<span class="strong">NoIndexScan(a)</span>*/ aid
+postgres$#     SELECT <span class="strong">/*+ NoIndexScan(a) */</span> aid
 postgres$#         INTO id FROM pgbench_accounts a WHERE aid = $1;
-postgres$#     SELECT /*+<span class="strong">SeqScan(a)</span>*/ count(*)
+postgres$#     SELECT <span class="strong">/*+ SeqScan(a) */</span> count(*)
 postgres$#         INTO cnt FROM pgbench_accounts a;
 postgres$#     RETURN id + cnt;
 postgres$# END;
 postgres$# $$ LANGUAGE plpgsql;
 </pre>
 </dd>
-<dt>オブジェクト名の引用符付け</dt>
+<dt>ヒント句内のオブジェクト名の文字ケース</dt>
+<dd>PostgreSQL は引用符で囲われないオブジェクト名を文字ケースを無視して扱いますが、pg_hint_plan は指定されたオブジェクト名の文字ケースはそのまま PostgreSQL の内部表現と比較します。つまり、ヒント句で TBL と指定した場合、データベース上で "TBL" と定義したもののみと合致し, TBL, tbl, Tbl など引用符で囲われないオブジェクト名とは合致しません。</dd>
+<dt>ヒント句内のオブジェクト名の引用符付け</dt>
 <dd>ヒントに記述するオブジェクト名や別名が括弧((、)のいずれか)、二重引用符(")、空白(スペース、タブ、改行のいずれか)を含む場合は、通常のSQL文で使う場合と同じように二重引用符(")で囲んでください。二重引用符を含むオブジェクト名は、全体を二重引用符で括ったうえで、内部に含む二重引用符を二重引用符でエスケープしてください(例: 「quoted"table"name」→「"quoted""table""name"」)。</dd>
 <dt>同一名称テーブルの区別</dt>
 <dd>スキーマ違いや同一テーブルの複数回使用などでクエリ中に同一名称のテーブルが複数回出現する場合は、テーブルに別名をつけてそれぞれのテーブルを区別してください。以下の例の1つ目のSQL文では、HashJoin(t1 t1)をヒントに指定したとき、ヒント句対象のオブジェクトが特定できずにエラーになっています。2つ目のSQL文では、各テーブルにptやstという別名をつけているため、実行計画作成時にヒントで指定した通りにHash Joinを選択しています。</p>
@@ -491,32 +555,8 @@ postgres-# JOIN public.t1 pt ON (st.id=pt.id);
 postgres=#</pre>
 </p>
 </dd>
-<dt>FROM句にVALUESコマンドを指定した場合の制限</dt>
-<dd>FROM句にVALUESコマンドを指定した場合は、ヒント句のオブジェクト名に「*VALUES*」を指定してください。これは、VALUESの結果に別名を指定しても、PostgreSQL本体側で「*VALUES*」に名称が置き換えられるためです。複数のVALUESを使用する場合、この動作によりヒント句の対象を特定できません。よって、実行計画を制御できません。
-<pre>
-postgres=# /*+ <span class="strong">MergeJoin(a *VALUES*)</span> */
-postgres-# EXPLAIN SELECT *
-postgres-#    FROM pgbench_accounts a
-postgres-#    JOIN (VALUES (1,1),(2,2)) <span class="strong">v</span> (vid, vbalance) ON a.aid = v.vid
-postgres-#   ORDER BY a.aid;
-                                                  QUERY PLAN
----------------------------------------------------------------------------------------------------------------
- <span class="strong">Merge Join</span>  (cost=0.04..4497.33 rows=2 width=105)
-   Merge Cond: (a.aid = "*VALUES*".column1)
-   ->  Index Scan using pgbench_accounts_pkey on pgbench_accounts a  (cost=0.00..4247.26 rows=100000 width=97)
-   ->  Sort  (cost=0.04..0.04 rows=2 width=8)
-         Sort Key: "*VALUES*".column1
-         ->  Values Scan on <span class="strong">"*VALUES*"</span>  (cost=0.00..0.03 rows=2 width=8)
-(6 行)
-
-postgres=#
-</pre>
-</dd>
-</dl>
-
-<h3>ヒントの適用対象の指定</h3>
 <dl>
-<dt>ã\82¯ã\82¨ã\83ªã\81«æ\98\8eè¨\98ã\81\95ã\82\8cã\81¦ã\81\84ã\81ªã\81\84ã\83\86ã\83¼ã\83\96ã\83«ã\81¸ã\81®ã\83\92ã\83³ã\83\88å\8f¥é\81©ç\94¨</dt>
+<dt>ã\83\93ã\83¥ã\83¼ã\81\8aã\82\88ã\81³ã\83«ã\83¼ã\83«ã\81®ä¸­ã\81§ã\82¢ã\82¯ã\82»ã\82¹ã\81\95ã\82\8cã\81¦ã\81\84ã\82\8bã\83\86ã\83¼ã\83\96ã\83«</dt>
 <dd>ヒント句で指定した名称と一致すれば、ビュー定義や関数内クエリなどに出現するテーブルについても、ヒントを指定したクエリ内と同じようにヒント句が適用されます。このため、ヒント句の適用有無や適用するヒント句をそれぞれのテーブルで変えたい場合は、それぞれ異なる別名を指定してください。</br>
 以下の例では、ビュー定義で使われている「t1」という別名をSeqScanヒント句で指定したことで、表スキャンとビュー経由のスキャンの両方でSeq Scanが選択されています。ビュー定義で使用されている「t1」とは別の別名を実表に指定することで、個別にスキャン方式を制御できます。
 <pre>
@@ -531,28 +571,12 @@ postgres=# EXPLAIN SELECT * FROM table1 <span class="strong">t1</span> JOIN view
          Filter: (key = 1)
    ->  Seq Scan on table1 <span class="strong">t1</span>  (cost=0.00..179.00 rows=1 width=8)
          Filter: (key = 1)
-(5 rows)
-
-postgres=# /*+ SeqScan(<span class="strong">t3</span>) */
-postgres=# EXPLAIN SELECT * FROM table1 <span class="strong">t3</span> JOIN view1 t2 ON (t1.key = t2.key) WHERE t2.key = 1;
-                                   QUERY PLAN
---------------------------------------------------------------------------------
- Nested Loop  (cost=0.00..187.29 rows=1 width=16)
-   ->  Seq Scan on table1 <span class="strong">t3</span>  (cost=0.00..179.00 rows=1 width=8)
-         Filter: (key = 1)
-   ->  Index Scan using foo_pkey on table1 t1  (cost=0.00..8.28 rows=1 width=8)
-         Index Cond: (key = 1)
-(5 rows)
-
 </pre>
 </dd>
-<dt>継承テーブルに対するヒント句</dt>
+<dt>継承テーブル</dt>
 <dd>継承テーブルにスキャン方式のヒント句を指定する場合は、オブジェクト名として親テーブルの名称または別名を指定してください。全ての子テーブルに同じスキャン方式を選択します。子テーブルごとに別のスキャン方式を指定することはできません。</dd>
-<dt>ビューやルールを使うクエリのヒント</dt>
-<dd>ルールを定義したテーブルやビューを複数用いるときに、各ビュー内のテーブルの別名やルール書き換え後のクエリのテーブルの別名が重複した場合は、ヒント句の対象を区別できません。区別する場合は、各ビュー内のテーブルの別名やルール書き換え後のクエリのテーブルの別名を重複させないでください。</dd>
-<dt>ルールを使うクエリでのヒントの適用範囲</dt>
-<dd>ルールによるクエリ書き換えによってクエリが複数になる場合は、書き換え前のクエリで指定したヒントが全てのクエリで使用されます。ルール内のクエリにヒントを記述しても、そのヒントは適用されません。</dd>
-<dt>マルチステートメントでのヒントの適用範囲</dt>
+
+<dt>マルチステートメント</dt>
 <dd>クエリをマルチステートメントで実行する場合は、ヒントの指定方法によって以下のように注意点が異なります。
 <dl>
 <dt>コメントでの指定</dt>
@@ -561,14 +585,35 @@ postgres=# EXPLAIN SELECT * FROM table1 <span class="strong">t3</span> JOIN view
 <dd>ヒントを指定したいクエリの定数部分を?に置き換えてから、全てのクエリを一つにまとめてヒント用テーブルに登録します。ただし、複数の動的クエリをマルチステートメントで実行する場合には対応していません。</dd>
 </dl>
 </dd>
-<dt>副問い合わせ結果をヒントに指定する方法</dt>
-<dd>以下の副問い合わせの結果をヒントに指定する場合は、ヒント句のオブジェクト名に「ANY_subquery」を指定してください。
+<dt>FROM句にVALUES式を使っている問い合わせ</dt>
+<dd>FROM句にVALUES式を使っている場合は、ヒント句のオブジェクト名に「*VALUES*」を指定することでヒントを与えることができる場合があります。 ただし複数のVALUESを使っている場合は内部的には区別がつかないためヒントを与えることはできません。
+<pre>
+postgres=# /*+ <span class="strong">MergeJoin(a *VALUES*)</span> */
+postgres-# EXPLAIN SELECT *
+postgres-#    FROM pgbench_accounts a
+postgres-#    JOIN (VALUES (1,1),(2,2)) <span class="strong">v</span> (vid, vbalance) ON a.aid = v.vid
+postgres-#   ORDER BY a.aid;
+                                                  QUERY PLAN
+---------------------------------------------------------------------------------------------------------------
+ <span class="strong">Merge Join</span>  (cost=0.04..4497.33 rows=2 width=105)
+   Merge Cond: (a.aid = "*VALUES*".column1)
+   ->  Index Scan using pgbench_accounts_pkey on pgbench_accounts a  (cost=0.00..4247.26 rows=100000 width=97)
+   ->  Sort  (cost=0.04..0.04 rows=2 width=8)
+         Sort Key: "*VALUES*".column1
+         ->  Values Scan on <span class="strong">"*VALUES*"</span>  (cost=0.00..0.03 rows=2 width=8)
+postgres=#
+</pre>
+</dd>
+</dl>
+
+<dt>副問い合わせ結果</dt>
+<dd>以下のような形式の副問い合わせでは外側の文への併合が行われず「ANY_subquery」という名前の独立した副問合せとして残される場合があります。このような副問合せが一つしかない場合は ANY_subquery という名前でこの副問合せを特定することができます。
 <ul>
-<li>IN (SELECT ... { LIMIT | OFFSET 等} ... )</li>
-<li>ANY (SELECT ... { LIMIT | OFFSET 等} ...)</li>
-<li>SOME (SELECT ... { LIMIT | OFFSET 等} ...)</li>
+<li>IN (SELECT ... { <span class="strong">LIMIT | OFFSET 等</span>} ... )</li>
+<li>ANY (SELECT ... { <span class="strong">LIMIT | OFFSET 等</span>} ...)</li>
+<li>SOME (SELECT ... { <span class="strong">LIMIT | OFFSET 等</span>} ...)</li>
 </ul>
-PostgreSQLは、実行計画を生成するときに副問い合わせを上位の問合せに併合することがあります。しかし、上記のような副問い合わせの場合には併合せず、これらの副問い合わせの結果に内部的に「ANY_subquery」という固定名をつけます。以下の例では、その固定名を指定したヒント句の効果でHash Joinを選択しています。
+以下の例では、そのことを利用して Hash Joinを強制しています。
 <pre>
 postgres=# /*+HashJoin(a1 ANY_subquery)*/
 postgres=# EXPLAIN SELECT *
@@ -587,15 +632,28 @@ postgres=#   WHERE aid IN (SELECT bid FROM pgbench_accounts a2 LIMIT 10);
 
 postgres=#
 </pre>
-一つのクエリで上記のような副問い合わせを複数使用している場合は、「ANY_subquery」と指定しても対象を特定できないため、ヒント句はエラーとなり無視されます。</br>
+
+<dt>IndexOnlyScanヒント句</dt>
+<dd>IndexOnlyScanヒントで指定されているインデックスで index only scan が実行できない場合は、index scan を他のインデックスで実行する可能性があります。</dd>
+
+<dt>NoIndexScanヒントの挙動について</dt>
+<dd>NoIndexScanヒント句を指定した場合は、Index ScanだけでなくIndex Only Scanも選択されません。</dd>
+</dl>
+
+<dt>UNION に対する並列実行ヒント</dt>
+<dd>UNIONは直下のサブクエリが全て並列実行可能な場合にだけ並列実行を行います。一方ですべてのサブクエリが並列実行可能な場合は、そのうちの一つで並列実行を強制するとコスト比較の結果UNION全体が並列実行されることになります。ただし並列実行ヒントによる並列実行の禁止を行った場合はそのスキャンは並列実行不可となります。
 </dd>
-<dt>IndexOnlyScanヒント句の指定(PostgreSQL 9.2以降)</dt>
-<dd>ヒント句の対象となるテーブルにIndex Only Scanが可能なインデックスとIndex Only Scanが不可能なインデックスが存在する場合、Index Only Scanが可能なインデックスをテーブルと併せてIndexOnlyScanヒント句に指定しないとIndex Scanが選択されることがあります。</dd>
-<dt>NoIndexScanヒント句の注意点(PostgreSQL 9.2以降)</dt>
-<dd>PostgreSQL 9.2以降でNoIndexScanヒント句を指定した場合は、Index ScanだけでなくIndex Only Scanも選択されません。</dd>
 </dl>
 
-<h3>ヒント指定エラーの扱い</h3>
+<dt>Set ヒントでの pg_hint_plan 自身の制御変数の設定</dt>
+<dd>pg_hint_plan 自身の挙動を設定する変数を Set ヒントで変更した場合は期待通りに動作しない場合があります。</dd>
+<ul>
+<li>enable_hint, enable_hint_tables の設定ヒントはログ上は「使用済み」と出ますが、実際には無視されています。</li>
+<li>debug_print と message_level の変更は処理の途中から影響を与えます。</li>
+</ul>
+</dd>
+
+<h2>ヒントのパースエラーについて</h2>
 <dt>構文エラー</dt>
 <dd>ヒント句の記述に構文上の誤りがあった場合、pg_hint_planは誤った記述より前のヒント句のみ有効とし、誤った記述以降のヒント句を無視してクエリを実行します。誤りの内容はpg_hint_plan.parse_messagesで指定したレベルでサーバログに記録されます。
 <ul>
@@ -605,47 +663,42 @@ postgres=#
 </ul>
 </dd>
 <dt>オブジェクト指定エラー</dt>
-<dd>pg_hint_planは、ヒント句対象のオブジェクト指定に誤りがあった場合、pg_hint_planは不正なヒント句のみを無視し、それ以外のヒント句を使ってクエリを実行します。誤りの内容はpg_hint_plan.parse_messagesで指定したレベルでサーバログに記録されます。誤ったオブジェクト指定の例を以下に示します。
+<dd>pg_hint_planは、ヒント句対象のオブジェクト指定に誤りがあった場合、pg_hint_planは正常に解析できたヒントのみを適用して、それ以外を無視します。誤りの内容はpg_hint_plan.parse_messagesで指定したレベルでサーバログに記録されます。
 <ul>
-<li>クエリ中に同じ名称のテーブル名または別名のテーブルがあり、それに対してヒント句を指定した。</li>
-<li>結合方式や結合順序のヒント句に同じオブジェクト名を複数回指定した。</li>
-</ul>
 </dd>
-<div class="tips">
-<span class="strong">構文エラーとオブジェクト指定エラーが同時に起こった場合</span>
-<p>構文エラーより前のヒント句の中から、オブジェクト指定エラーでないヒント句を適用します。</p>
-</div><br>
-<dt>指定するヒント句の種類の重複</dt>
+
+<dt>重複したヒント</dt>
 <dd>同じオブジェクトに対して同じグループのヒント句を重複して指定した場合は、各グループで最後に指定したヒント句を使用します。</dd>
 <dt>ネストしたブロックコメント</dt>
 <dd>pg_hint_planでは、ヒントを指定したブロックコメントにネストしたブロックコメントを含めることができません。ネストしたブロックコメントを含めた場合は、誤った記述に関する情報を出力しますがエラー終了しません。ヒントを無視してクエリを実行します。</dd>
 <dt>メッセージの出力レベル</dt>
 <dd>ヒントに誤りがあった場合に出力されるメッセージのレベルは、基本的にはpg_hint_plan.parse_messagesに指定したレベルです。ただし、ヒント句に指定したオブジェクトの長さが識別子の最大長(デフォルトでは63バイト)を超えた際に切り詰めた場合は、NOTICEで出力します。</dd>
 
-<h3>機能制限</h3>
-<dt>標準のGUCパラメータの影響</dt>
-<dd>FROMリストの数がfrom_collapse_limitの設定値以上の場合、またはFROMリストの数がjoin_collapse_limitの設定値より大きい場合は、結合順序のヒント句が無視されます。また、FROMリストの数がgeqo_thresholdの設定値以上の場合は、結合順序のヒント句、および結合方式のヒント句が無視されます。ヒント句が使われるようにするには、これらのGUCパラメータの値を大きくしてください。</dd>
-<dt>ヒント句で制御できないケース</dt>
-<dd>pg_hint_planでは、PostgreSQLのプランナが候補としてあげる事ができない実行計画をヒント句に指定しても、その実行計画を生成することはできません。PostgreSQLのプランナが候補としてあげる事ができない実行計画の例を以下に示します。
+<h2>注意事項</h2>
+<dt>プランナパラメータの影響</dt>
+<dd>FROM句の要素数が from_collapse_limit 以上または join_collapse_limit を超える場合には、結合順序のヒント句は正しく動作しません。また、FROM句の要素数が geqo_threshold 以上の場合は、結合順序のヒント句、および結合方式のヒント句は動作しません。ヒント句が使われるようにするには、これらのGUCパラメータの値を十分に大きくしてください。</dd>
+<dt>実行不能なプランを指定するヒント</dt>
+<dd>ヒントで指定した結果正しく実行できない実行計画が生成される場合は、実行可能なプランに強制的に修正します。実行不能な実行計画例を以下に示します。
 <ul>
-<li>FULL OUTER JOINではNested Loopは、プランナが実行計画の候補として扱いません。</li>
-<li>WHEREå\8f¥ã\82\84JOINæ\9d¡ä»¶ã\81ªã\81©ã\81«æ\8c\87å®\9aã\81\97ã\81¦ã\81\84ã\81ªã\81\84å\88\97ã\81®ã\81¿ã\82\92å\90«ã\82\80ã\82¤ã\83³ã\83\87ã\83\83ã\82¯ã\82¹ã\81¯ã\80\81ã\83\97ã\83©ã\83³ã\83\8aã\81\8cå®\9fè¡\8cè¨\88ç\94»ã\81®å\80\99è£\9cã\81¨ã\81\97ã\81¦æ\89±ã\81\84ã\81¾ã\81\9bã\82\93ã\80\82</li>
-<li>æ¤\9cç´¢æ\9d¡ä»¶ã\81«ctidã\82\92æ\8c\87å®\9aã\81\97ã\81ªã\81\84å ´å\90\88ã\81¯Tid Scanã\81¯ã\80\81ã\83\97ã\83©ã\83³ã\83\8aã\81\8cå®\9fè¡\8cè¨\88ç\94»ã\81®å\80\99è£\9cã\81¨ã\81\97ã\81¦æ\89±ã\81\84ã\81¾ã\81\9bã\82\93。</li>
+<li>特殊な場合を除いた FULL OUTER JOINに対する Nested Loop。</li>
+<li>WHERE句やJOIN条件などに指定していない列のみを含むインデックス。</li>
+<li>æ¤\9cç´¢æ\9d¡ä»¶ã\81«ctidã\82\92æ\8c\87å®\9aã\81\97ã\81ªã\81\84å ´å\90\88ã\81® Tid Scan。</li>
 </ul>
 </dd>
 <dt>ECPGにおける制限</dt>
-<dd>ECPGで実装したアプリケーションから発行するクエリにヒントをコメントで指定した場合、実行計画を制御できません。これは、CプリプロセッサがCコードに変換するタイミングで、全てのブロックコメントを取り除いてしまうためです。ただし、C言語文字列に格納したクエリをEXECUTEコマンドで実行する動的SQLの場合は、コメントでヒントを指定しても実行計画を制御できます。</dd>
-<dt>ヒントによるフィンガープリントの変化</dt>
-<dd>SQLコメントでヒントを指定した場合、SQL文フィンガープリントベースのクエリキャッシュなどでは、ヒントが異なれば別のSQL文として扱われます。pg_stat_statementも9.1では別クエリとして集計しますが、9.2ではクエリ集約機能によりコメントが除去されるので、コメントで指定したヒントのみが異なるクエリは同じクエリとして扱われます。</dd>
+<dd>ECPGで実装したアプリケーションから発行するクエリにヒントをコメントで指定した場合、実行計画を制御できません。これは、CプリプロセッサがCコードに変換するタイミングで、全てのブロックコメントを取り除いてしまうためです。ただし、EXECUTEコマンドで実行する動的SQLに含まれるコメントは使用可能です。</dd>
+<dt>異なるヒントを与えた同一クエリの pg_stat_statements での扱い</dt>
+<dd>pg_stat_statements ではクエリIDの生成の際にコメントは無視されます。そのため与えているヒントが異なる同一のクエリは一つのクエリとして集計されます。</dd>
 
 </dl>
 
 <h2 id="requirement">動作環境</h2>
+pg_hint_plan14 1.6 は PostgreSQL 14 のみをサポートします。
 <dl>
 <dt>PostgreSQL</dt>
-  <dd>バージョン 9.1.4、9.2.1</dd>
-<dt>動作検証済みOS</dt>
-  <dd>RHEL 6.1</dd>
+  <dd>バージョン 14</dd>
+<dt>動作確認済みOS</dt>
+  <dd>CentOS 8.5</dd>
 </dl>
 
 <h2 id="seealso">関連項目</h2>
@@ -653,25 +706,13 @@ postgres=#
 <a href="http://www.postgresql.jp/document/current/html/sql-explain.html">EXPLAIN</a>
 <a href="http://www.postgresql.jp/document/current/html/sql-set.html">SET</a>
 <a href="http://www.postgresql.jp/document/current/html/runtime-config.html">サーバの設定</a>
+<a href="http://www.postgresql.jp/document/current/html/parallel-plans.html">パラレルプラン</a>
 <hr>
 
 <div class="navigation">
   <a href="pg_hint_plan-ja.html">pg_hint_plan</a>
 </div>
 
-<p class="footer">Copyright (c) 2012-2013, NIPPON TELEGRAPH AND TELEPHONE CORPORATION</p>
-
-<!--
-<script type="text/javascript">
-var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
-document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
-</script><script src="pg_statsinfo-ja_files/ga.js" type="text/javascript"></script>
-<script type="text/javascript">
-try{
-var pageTracker = _gat._getTracker("UA-10244036-6");
-pageTracker._trackPageview();
-} catch(err) {}
-</script>
--->
+<p class="footer">Copyright (c) 2012-2022, NIPPON TELEGRAPH AND TELEPHONE CORPORATION</p>
 </body>
 </html>