はじめに
一つのテーブルに対して複数のプロジェクションが存在する場合は、実行されるクエリの内容に応じてVerticaは最適なプロジェクションを使用します。
使用するプロジェクションの判断はVerticaのオプティマイザが行いますが、SQLヒントを利用することで、使用したい(使用させたくない)プロジェクションをユーザ自身で強制(指定)することもできます。
使用したいプロジェクションを強制する場合
使用したいプロジェクションを強制する場合はクエリ実行時に、PROJSというSQLヒントを指定します。
SELECT col1,col2... FROM テーブル名 /*+ PROJS(プロジェクション名) */ ;※PROJSヒントはSELECT句の後ではなく、FROM句のテーブル名の後に記載する必要があります。
使用例
以下は、通常は「t1_test1_node0001」プロジェクションが利用されるクエリで「t1_test2_node0001」プロジェクションの利用を強制する例です。
※t1テーブルには「t1_test1_node0001」、「t1_test2_node0001」、「t1_test3_node0001」という3つのプロジェクションが存在しています。
PROJSヒントを利用しない場合
実行計画を確認すると、このクエリは通常はt1_test1_node0001が使用されることが確認できます。
dbadmin=> EXPLAIN SELECT * FROM t1;
------------------------------
QUERY PLAN DESCRIPTION:
------------------------------
EXPLAIN SELECT * FROM t1;
Access Path:
+-STORAGE ACCESS for t1 [Cost: 51, Rows: 3] (PATH ID: 1)
| Projection: public.t1_test1_node0001 ★クエリ実行に使用するプロジェクション※実行計画(EXPLAIN)の詳細は以下の記事をご参考ください。
SQLの実行計画を確認する方法
https://www.ashisuto.co.jp/cm/analytics-database/sql-plan.html
PROJSヒントを利用した場合
実行計画を確認するとPROJSヒントを利用した場合はt1_test2_node0001が使用されることが確認できます。
dbadmin=> EXPLAIN SELECT * FROM t1 /*+ PROJS(t1_test2_node0001) */;
------------------------------
QUERY PLAN DESCRIPTION:
------------------------------
EXPLAIN SELECT * FROM t1 /*+ PROJS(t1_test2_node0001) */;
Access Path:
+-STORAGE ACCESS for t1 [Cost: 51, Rows: 3] (PATH ID: 1)
| Projection: public.t1_test2_node0001 ★クエリ実行に使用するプロジェクション使用させたくないプロジェクションを強制する場合
使用させたくないプロジェクションを強制する場合はクエリ実行時に、SKIP_PROJSというSQLヒントを指定します。
SELECT col1,col2... FROM テーブル名 /*+ SKIP_PROJS(プロジェクション名) */ ;※PROJSヒントはSELECT句の後ではなく、FROM句のテーブル名の後に記載する必要があります。
使用例
以下は「t1_test1_node0001」、「t1_test2_node0001」プロジェクションを使用させないようにする例です。
SKIP_PROJSヒントを利用しない場合
実行計画を確認すると通常はt1_test2_node0001が使用されることが確認できます。
dbadmin=> EXPLAIN SELECT * FROM t1 WHERE col2 ='aaa';
------------------------------
QUERY PLAN DESCRIPTION:
------------------------------
EXPLAIN SELECT * FROM t1 WHERE col2 ='aaa';
Access Path:
+-STORAGE ACCESS for t1 [Cost: 37, Rows: 2] (PATH ID: 1)
| Projection: public.t1_test2_node0001 ★クエリ実行に使用するプロジェクションSKIP_PROJSヒントを利用した場合
実行計画を確認するとt1_test1_node0001、t1_test2_node0001は使用されず、test3_node0001が使用されることが確認できます。
dbadmin=> EXPLAIN SELECT * FROM t1 /*+ SKIP_PROJS(t1_test1_node0001,t1_test2_node0001) */ WHERE col2 ='aaa';
------------------------------
QUERY PLAN DESCRIPTION:
------------------------------
EXPLAIN SELECT * FROM t1 /*+ SKIP_PROJS(t1_test1_node0001,t1_test2_node0001) */ WHERE col2 ='aaa';
Access Path:
+-STORAGE ACCESS for t1 [Cost: 52, Rows: 2] (PATH ID: 1)
| Projection: public.t1_test3_node0001 ★クエリ実行に使用するプロジェクション複数テーブルを結合するようなクエリの場合
複数テーブルを結合するようなクエリの場合は、各テーブル名の後ろにそれぞれヒントを記載します。
dbadmin=> SELECT * FROM t1 /*+PROJS('t1_test3_node0001')*/ ,
dbadmin-> t2 /*+PROJS('t2_test3_node0001')*/
dbadmin-> WHERE t1.col1=t2.col1;その他のヒント句については以下の記事をご参考ください。
SQLヒントを利用する(7.2新機能)
https://www.ashisuto.co.jp/cm/analytics-database/sql_hint_7-2.html
検証バージョンについて
この記事の内容はVertica 9.2で確認しています。
更新履歴
2019/04/22 検証バージョンを9.2に変更
2016/01/15 本記事を公開