17.00 - 17.05 - EXPLAINリクエスト修飾子およびパーティション プライマリ インデックスアクセス - Advanced SQL Engine - Teradata Database

Teradata Vantage™ - SQLリクエストおよびトランザクション処理

Product
Advanced SQL Engine
Teradata Database
Release Number
17.00
17.05
Published
2020年6月
Content Type
プログラミング リファレンス
ユーザー ガイド
Publication ID
B035-1142-170K-JPN
Language
日本語 (日本)

EXPLAINレポートは問合わせ最適化中に実行されるパーティション アクセス、削除、結合、および除外を指定します。

パーティション プライマリ インデックスの例

ここに示す1組の例では、パーティション プライマリ インデックスを持つテーブルに対する問合わせの最適化に関連する、より重要なEXPLAINテキストの句について説明します。

次の例にSELECTリクエストの行パーティションのサブセットにアクセスするためのEXPLAINレポートの一部を示します。該当する句は太字で強調表示されています。

CREATE TABLE t1 (
a INTEGER,
b INTEGER)
PRIMARY INDEX(a) 
PARTITION BY RANGE_N(b BETWEEN 1
                       AND    10
                       EACH    1);
   
EXPLAIN 
SELECT *
FROM t1
WHERE b > 2;
...
3) We do an all-AMPs RETRIEVE step in TD_MAP1 from 8 partitions of
   mws.t1 with a condition of ("mws.t1.b >= 3") into Spool 1
   (group_amps), which is built locally on the AMPs.  The size of
   Spool 1 is estimated with no confidence to be 3 rows (129 bytes).
   The estimated time for this step is 0.15 seconds.
...

次の例に、パーティション列についての等号制約のあるSELECTリクエストのEXPLAINレポートの一部を示します。該当する句は太字で強調表示されています。このレポートでは1つの行パーティション内のすべての行が全AMPを対象にスキャンされることを示しています。

CREATE TABLE t1 (a INTEGER, b INTEGER)
PRIMARY INDEX(a) 
PARTITION BY RANGE_N(b BETWEEN 1
                       AND    10
                       EACH    1);

EXPLAIN 
SELECT *
FROM t1
WHERE t1.b = 1;
...
3) We do an all-AMPs RETRIEVE step from  a single partition of  mws.t1
   with a condition of ("mws.t1.b = 1") into Spool 1
   (group_amps), which is built locally on the AMPs. The size of
   Spool 1 is estimated with no confidence to be 2 rows. The
   estimated time for this step is 0.15 seconds.
...

次の例では、行パーティション列についての制約がないパーティション プライマリ インデックスアクセスに関するEXPLAINリクエスト レポートの一部を示します。該当する句は太字で示されています。このレポートでは、単一のAMP上で対象となるプライマリ インデックス値のすべての行パーティションがアクセスされることを示しています。

CREATE TABLE t1 (a INTEGER, b INTEGER)
PRIMARY INDEX(a)
PARTITION BY RANGE_N(b BETWEEN 1
                       AND    10
                       EACH 1);

EXPLAIN 
SELECT *
FROM t1
WHERE t1.a = 1;
1) First, we do a single-AMP RETRIEVE step from  all partitions of
   mws2.t1 by way of the primary index "mws2.t1.a = 1" with no
   residual conditions into Spool 1 (one_amp), which is built
   locally on that AMP. The size of Spool 1 is estimated with low
   confidence to be 2 rows. The estimated time for this step is 0.15 seconds.
...

次の例では、行パーティション排除なしでのSELECTリクエストの処理が示されています。句n partitions ofはこのレポートでは発生しません。

CREATE TABLE t1 (a INTEGER, b INTEGER)
PRIMARY INDEX(a)
PARTITION BY RANGE_N(b BETWEEN 1
                       AND    10
                       EACH    1);

EXPLAIN 
SELECT *
FROM t1
WHERE b>-1;
...
3) We do an all-AMPs RETRIEVE step in TD_MAP1 from mws.t1 by way of
   an all-rows scan with a condition of ("NOT (mws.t1.b IS NULL)")
   into Spool 1 (group_amps), which is built locally on the AMPs.
   The size of Spool 1 is estimated with low confidence to be 8 rows
   (344 bytes).  The estimated time for this step is 0.15 seconds.
...

2つのステップが生成され、次のEXPLAINレポートの一部で示すように、それぞれ部分および完全行パーティション削除が実行されます。該当する句は太字で表示されます。

CREATE TABLE t2 (
a INTEGER,
b INTEGER)
PRIMARY INDEX(a)
PARTITION BY RANGE_N(b BETWEEN 1 
                       AND    10
                       EACH 2);

EXPLAIN 
DELETE FROM t2
WHERE b BETWEEN 4 AND 7;
...
3) We do an all-AMPs DELETE from  2 partitions of  mws.t2
   with a condition of ("(mws.t2.b <= 7) AND (mws.t2.b >= 4)").
4) We do an all-AMPs DELETE  of a single partition  from mws.t2 with a
   condition of ("(mws.t2.b <= 7) AND (mws.t2.b >= 4)").
...
EXPLAIN 
DELETEFROM t2
WHERE b BETW EEN 4 AND 8;
...
3) We do an all-AMPs DELETE from  a single partition of  mws.t2
   with a condition of ("(mws.t2.b <= 8) AND (mws.t2.b >= 4)").
4) We do an all-AMPs DELETE  of 2 partitions  from mws.t2 with a
   condition of ("(mws.t2.b <= 8) AND (mws.t2.b >= 4)").
...

次の例では、行パーティション プライマリ インデックスおよびRowkeyベースのマージ結合を含むスプールを示します。該当する句は太字で表示されます。

CREATE TABLE t3 (
a INTEGER,
b INTEGER)
PRIMARY INDEX(a);

CREATE TABLE t4 (
a INTEGER,
b INTEGER)
PRIMARY INDEX(a)
PARTITION BY b;

EXPLAIN 
SELECT *
FROM t3, t4
WHERE t3.a = t4.a
AND   t3.b = t4.b;
...
4) We do an all-AMPs RETRIEVE step in TD_MAP1 from mws.t3 by way of
   an all-rows scan with a condition of ("(NOT (mws.t3.a IS NULL ))
   AND ((mws.t3.b <= 65535) AND (mws.t3.b >= 1 ))") into Spool 2
   (all_amps), which is built locally on the AMPs.  Then we do a SORT to partition Spool 2 by rowkey.  The size of Spool 2 is estimated
   with no confidence to be 2 rows (42 bytes).  The estimated time
   for this step is 0.05 seconds.
5) We do an all-AMPs JOIN step in TD_MAP1 from mws.t4 by way of a
   RowHash match scan, which is joined to Spool 2 (Last Use) by way
   of a RowHash match scan.  mws.t4 and Spool 2 are joined using a
   rowkey-based merge join, with a join condition of ("(b = mws.t4.b)
   AND (a = mws.t4.a)").  The result goes into Spool 1 (group_amps),
   which is built locally on the AMPs.  The size of Spool 1 is
   estimated with no confidence to be 2 rows (130 bytes).  The
   estimated time for this step is 0.09 seconds.
...

次の例では、同じパーティション化キーとプライマリ キーを持つ2つのテーブルを結合する1つのステップを示します。該当する句は太字で表示されます。

CREATE TABLE orders (
   o_orderkey      INTEGER NOT NULL,
   o_custkey       INTEGER,
   o_orderstatus   CHARACTER(1) CASESPECIFIC,
   o_totalprice    DECIMAL(13,2) NOT NULL,
   o_orderdate     DATE FORMAT 'yyyy-mm-dd' NOT NULL,
   o_orderpriority CHARACTER(21),
   o_clerk         CHARACTER(16),
   o_shippriority  INTEGER,
   o_comment       VARCHAR(79))
PRIMARY INDEX (o_orderkey)
PARTITION BY RANGE_N(o_orderdate BETWEEN DATE '1992-01-01'
                                 AND     DATE '1998-12-31'
                                 EACH INTERVAL '1' MONTH)
UNIQUE INDEX (o_orderkey);
CREATE TABLE lineitem (
  l_orderkey      INTEGER NOT NULL,
  l_partkey       INTEGER NOT NULL,
  l_suppkey       INTEGER,
  l_linenumber    INTEGER,
  l_quantity      INTEGER NOT NULL,
  l_extendedprice DECIMAL(13,2) NOT NULL,
  l_discount      DECIMAL(13,2),
  l_tax           DECIMAL(13,2),
  l_returnflag    CHARACTER(1),
  l_linestatus    CHARACTER(1),
  l_shipdate      DATE FORMAT 'yyyy-mm-dd',
  l_commitdate    DATE FORMAT 'yyyy-mm-dd',
  l_receiptdate   DATE FORMAT 'yyyy-mm-dd',
  l_shipinstruct  VARCHAR(25),
  l_shipmode      VARCHAR(10),
  l_comment       VARCHAR(44))
PRIMARY INDEX (l_orderkey)
PARTITION BY RANGE_N(l_shipdate BETWEEN DATE '1992-01-01'
                                AND     DATE '1998-12-31'
                                EACH INTERVAL '1' MONTH);

EXPLAIN 
SELECT *
FROM lineitem, ordertbl
WHERE  l_orderkey = o_orderkey
AND    l_shipdate = o_orderdate
AND   (o_orderdate < DATE '1993-10-01')
AND   (o_orderdate >= DATE '1993-07-01')
ORDER BY o_orderdate, l_orderkey;
...
3) We do an all-AMPs JOIN step from  3 partitions of  TH.ORDERTBL
   with a condition of (
   "(TH.ORDERTBL.O_ORDERDATE < DATE '1993-10-01') AND
   (TH.ORDERTBL.O_ORDERDATE >= DATE '1993-07-01')"),
   which is joined to TH.LINEITEM with a condition of (
   "TH.LINEITEM.L_COMMITDATE < TH.LINEITEM.L_RECEIPTDATE").
   TH.ORDERTBL and TH.LINEITEM are joined using a rowkey-based
   inclusion merge join, with a join condition of (
   "TH.LINEITEM.L_ORDERKEY = TH.ORDERTBL.O_ORDERKEY").
   The input tables TH.ORDERTBL and TH.LINEITEM will
   not be cached in memory. The result goes into Spool 3 (all_amps),
   which is built locally on the AMPs. The size of Spool 3 is
   estimated with no confidence to be 7,739,047 rows. The
   estimated time for this step is 1 hour and 34 minutes.
...

次の例では集約での行パーティション排除を示します。該当する句は太字で表示されます。

CREATE TABLE t1 (
a INTEGER,
b INTEGER)
PRIMARY INDEX(a) 
PARTITION BY RANGE_N(b BETWEEN 1
                       AND    10
                       EACH 1);

EXPLAIN 
SELECT MAX(a)
FROM t1
WHERE b > 3;
...
3) We do an all-AMPs SUM step in TD_MAP1 to aggregate from 7 partitions of
   mws.t1 with a condition of ("mws.t1.b >= 4").
   Aggregate Intermediate Results are computed globally, then placed
   in Spool 3 in TD_Map1.  The size of Spool 3 is estimated with high
   confidence to be 1 row (19 bytes).  The estimated time for this
   step is 0.21 seconds.
4) We do an all-AMPs RETRIEVE step in TD_Map1 from Spool 3 (Last Use)
   by way of an all-rows scan into Spool 1 (group_amps), which is
   built locally on the AMPs.  The size of Spool 1 is estimated with
   high confidence to be 1 row (32 bytes).  The estimated time for
   this step is 0.03 seconds.
...

この説明内の新しい用語は、次のように定義されます。

定義
n partitions of n個の行パーティションだけアクセスされます。n > 1です。この例では、n = 8です。
a single partition of このリクエストの処理では1つの行パーティションだけにアクセスされます。
all partitions of このリクエストの処理ではプライマリ インデックスアクセスによって対象となるすべての行パーティションがアクセスされます。
of a single partition 最適化ルーチンは単一行パーティションのすべての行を削除できることを特定しています。場合によっては、これはパーティション全体のより高速な削除が可能になります。
of n partitions 最適化ルーチンは各n行パーティションのすべての行が削除できることを特定しています。ここで、n > 1です。場合によっては、このことにより行パーティション全体のより高速な削除が可能になります。
SORT to partition Spool n by rowkey。 最適化ルーチンが、スプールが結合されるテーブルと同じパーティション式に基づいて行パーティション化されることを決定しました。

つまり、スプールはrowkeyに基づいてソートされます(パーティションおよびハッシュ)。この方法でスプールをパーティション化することで、行パーティション化されたテーブルを使用した高速な結合が可能になります。

nはスプール番号です。

a rowkey-based この結合は行パーティション(rowkey)に基づくハッシュ ベースです。この場合、パーティションおよびプライマリ インデックス列の両方に対する等号制約があります。このことにより、さらに高速な結合が可能になります。非排除行パーティションはそれぞれ、最大でも1つだけの他の行パーティションと結合する必要があるためです。

この句がレポートされていない場合、結合はハッシュ ベースです。つまり、ハッシュが派生するプライマリ インデックス列に等号制約があります。行パーティション化されたテーブルでは、ハッシュ順でのテーブルの処理によって追加のオーバーヘッドが発生します。

なお、いずれの方法でも結合条件が検証される必要があります。