ALTER TABLE TO CURRENTリクエストの一般的な使用の指針とルール - Advanced SQL Engine - Teradata Database

Teradata Vantage™ - SQLデータ定義言語 詳細トピック

Product
Advanced SQL Engine
Teradata Database
Release Number
17.05
17.00
Published
2020年6月
ft:locale
ja-JP
ft:lastEdition
2021-03-30
dita:mapPath
ja-JP/jpx1556733107962.ditamap
dita:ditavalPath
ja-JP/jpx1556733107962.ditaval
dita:id
B035-1184
Product Category
Software
Teradata Vantage

日付またはタイムスタンプの定数が有効であれば、パーティション式のどの場所にもDATE、CURRENT_DATE、またはCURRENT_TIMESTAMP関数を指定することができますが、これらの関数の使用方法には十分に注意する必要があります。

ある範囲の中でDATE関数またはCURRENT_DATE関数を使用して複数の範囲を指定し、CURRENT_DATEを使用して指定した範囲のパーティションを後で調整する場合に、既存の範囲と重複することがあります。このような場合は、調整はリクエスト側にエラーを返します。このようなエラーが発生した場合は、DATEまたはCURRENT_DATEに基づいた新しいパーティション式でテーブルを再作成する必要があります。このため、範囲内でDATEまたはCURRENT_DATE関数を使用するパーティション式を設計する場合には、注意が必要です。

データを1つ以上のカレント パーティションおよび1つ以上の履歴パーティションとしてパーティション化する必要があり、カレントおよび履歴の期間が、パーティション式で解釈されたDATE、CURRENT_DATE、またはCURRENT_TIMESTAMPの値で定義されている場合に、パーティション式のDATE、CURRENT_DATE、およびCURRENT_TIMESTAMP関数は最も適しています。

これにより、テーブルまたは結合インデックスを定期的に調整し、カレント パーティションの古いデータを1つ以上の履歴パーティションへ移動できます。これには、ALTER TABLEリクエストで範囲をADDまたはDROPしてそれぞれ明示的な日付でパーティションを再定義するのではなく、ALTER TABLE TO CURRENTリクエストを使用します。テーブルまたは結合インデックスでこれらの式を定義する前に、パーティション式でDATE、CURRENT_DATE、またはCURRENT_TIMESTAMP関数でどのような調整が必要なのかを評価すべきです。

結合インデックスの場合、述部でDATE、CURRENT_DATE、またはCURRENT_TIMESTAMP関数を指定している場合には、調整にWHERE句が含まれます。この場合も、実際の現在日付または現在のタイムスタンプ値は、常に、パーティション式内で解釈されたDATE、CURRENT_DATE、またはCURRENT_TIMESTAMPよりも前になり、ALTER TABLE TO CURRENTリクエストが完了した後で新しく解釈された値に基づいて調整されます。

ALTER TABLE TO CURRENTリクエストを使用して、パーティション式で新しく解釈されたDATE、CURRENT_DATE、またはCURRENT_TIMESTAMP値で行を調整することは、効率的ではありません。これは、テーブルまたは結合インデックスをスキャンして調整が必要な行を見つけるのに時間がかかること、およびテーブルに対するALTER TABLE TO CURRENTリクエストでWITH DELETEまたはWITH INSERT句を指定した場合に、調整が必要な行を移動または削除するのに時間がかかることが原因です。結合インデックスに作成されたALTER TABLE TO CURRENTリクエストに対しては、nullパーティション ハンドラーを指定できません。

パーティション全体を削除するなど、最適化せずにテーブルのかなりの比率の行の調整が必要な場合、別の形式のパーティションの方が適していることが考えられます。

ALTER TABLE TO CURRENTリクエストを作成する場合には、修飾されていないDATE関数またはCURRENT_DATE関数を指定するよりも、DATE - INTERVAL '2' DAYCURRENT_DATE - INTERVAL '2' DAYや他の適切な調整で修飾した関数をパーティション式の中に指定すべきです。これは、ALTER TABLE TO CURRENTリクエストが実行されたセッション タイムゾーンとは異なるタイムゾーンでリクエストが実行される可能性があるためです。このような調整により、セッションのタイムゾーンに関係なく、同じリクエストに対する最適化ルーチンのクエリー計画が同じになります。

CURRENT_TIMESTAMP関数を使用するパーティション式を指定すると、DATE関数またはCURRENT_DATE関数を使用するパーティション式で発生するタイムゾーンの問題を回避することができます。また、これらのパーティション式で、全般的に適用されるための調整が不要になります。

ALTER TABLE TO CURRENTリクエストに関するルールは、行パーティションと列パーティションで同じですが、テーブルまたは結合インデックスに行パーティションと列パーティションの両方があると、パフォーマンスに悪影響が出る可能性があります。テーブルの行を行パーティション間で移動する操作には、大きなコストがかかる場合が多いからです。

ALTER TABLE TO CURRENT文には、次の一般的なルールが適用されます。
  • パーティション定義の中で、DATE関数またはCURRENT_DATE関数とCURRENT_TIMESTAMP関数のいずれかまたは両方を使用してパーティション化したテーブルまたは結合インデックスの場合は、ALTER TABLE TO CURRENTリクエストを使用して、新しく解釈された日付またはタイムスタンプへの調整を行なうことができます。ALTER TABLE TO CURRENTリクエストは、現在の設定値に基づいて、DATE、CURRENT_DATE、CURRENT_TIMESTAMPの値を解釈し、それに基づいてパーティションを調整します。
  • ALTER TABLE TO CURRENTリクエストを実行する場合に、指定のテーブルまたは結合インデックスのパーティションで、DATE、CURRENT_DATE、CURRENT_TIMESTAMPのいずれかの関数が指定されていない場合、データベースはリクエスト元にエラーを返します。

    結合インデックスのWHERE句でDATE、CURRENT_DATE、またはCURRENT_TIMESTAMP関数を指定することも可能です。その場合、データベースは、リクエストをアボートせず、リクエスト側にエラーを返すこともありません。

    エラーが発生するのは、DATE、CURRENT_DATE、またはCURRENT_TIMESTAMPのいずれかの関数が、パーティション式と結合インデックス定義のWHERE句のどちらにおいても指定されていない場合だけです。

  • ALTER TABLE TO CURRENTリクエストを実行すると、データベースは、新しく解釈された現在日付、または現在のタイムスタンプ値を使用してパーティション式を評価します。調整の対象となるテーブルまたは結合インデックス内の行がスキャンされ、行を新しいパーティションへ移動するか、または、(ALTER TABLE TO CURRENT操作の結果としてすでにパーティションに関連付けられていない場合は)行を削除することにより、行が調整されます。
    • 結合インデックスに対してnullパーティション ハンドラーを指定すると、データベースはリクエスト元にエラーを返します。このエラーは、この文を使用して結合インデックスから行を削除できないために発生します。
    • nullパーティション ハンドラーを指定せず、新しく調整されたパーティション式によって無効にされた行がある場合、データベースはリクエスト元にエラーを返します。

      結合インデックスに対してnullパーティション ハンドラーは指定できないため、DATE、CURRENT_DATE、またはCURRENT_TIMESTAMPを使ってインデックスに定義されたパーティションは、ALTER TABLE TO CURRENTリクエストによってこのエラーを生じないパーティションである必要があります。そうしないと、結合インデックスは新しい日付またはタイムスタンプ値に合わせて調整されない可能性があります。

      この場合、既存の結合インデックスを削除し、該当するパーティション定義を使用して新しいインデックスを作成する必要があります。

  • 調整中にテーブルの行が移動または削除された場合、データベースは関連するセカンダリ インデックス、結合インデックス、およびハッシュ インデックスを必要に応じてすべて更新します。
  • WITH DELETE句またはWITH INSERT句の任意のを指定する場合は、table_nameのすべての削除トリガーを無効にする必要があります。

    また、WITH INSERT句を指定する場合は、table_nameのすべての挿入トリガーを無効にする必要があります。このような挿入トリガーを無効にしない場合、データベースはリクエスト元にエラーを返します。

    ALTER TABLE TO CURRENTリクエストを正常に実行できたら、無効にしたこれらのトリガーをもう一度有効にする必要があります。

  • 新たに解決された日付またはタイムスタンプ値が、前に調整された日付またはタイムスタンプよりも前の日付またはタイムスタンプと評価されると、データベースはリクエスト元にエラーを返します。

    このような日付またはタイムスタンプは、クロックのずれ、システム クロックへの調整、または日付についてのセッション時間の差によって生じる可能性がありますが、調整は頻繁には生じないため、クロックのリセットまたは調整によって、現在日付またはタイムスタンプの値が逆行することはないでしょう。

    想定している調整の使い方は、日付およびタイムスタンプの値が常に進んでいるという仮定に基づいており、このような日付およびタイムスタンプの解釈問題が生じることは予測されていません。

  • 基本テーブルまたは結合インデックスに対して最後に解釈された日付またはタイムスタンプは、テーブルDBC.TVMに保持されています。
  • 新しく解釈された日付が、(DATE関数またはCURRENT_DATE関数を含んでいる)RANGE_N関数の最初の式を、あるパーティション境界と評価した場合、データベースは、このパーティションよりも前のパーティションをすべて削除します。それ以外の場合、データベースは、新しいパーティション式を使用してテーブル全体を再パーティション化します。

    たとえば、2006年4月1日に実行された、次のようなCREATE TABLEリクエストについて考えてみましょう。

         CREATE TABLE ppi (
           i INTEGER,
           j DATE)
         PRIMARY INDEX(i) 
         PARTITION BY RANGE_N(j BETWEEN CURRENT_DATE
                                AND     CURRENT_DATE+INTERVAL'1' YEAR -                                                 INTERVAL'1' DAY
                                EACH INTERVAL'1' MONTH);

    この例では、最後に解釈された日付は2006年4月1日で、DATEまたはCURRENT_DATEの値がDATE '2006-06-01'であると仮定して、ALTER TABLE TO CURRENTリクエストを実行します。新しく解釈されたDATEまたはCURRENT_DATE値での最初の式は、3番目のパーティションのパーティション境界にあたります。このため、データベースはパーティション1とパーティション2を削除し、最終の調整日付が、新しく解釈されたDATEまたはCURRENT_DATEの値に設定されます。

    ここで、DATE '2006-06-10'にALTER TABLE TO CURRENTリクエストを実行すると考えてみましょう。新しく解釈されたDATEまたはCURRENT_DATE値での最初の式は、パーティション境界にない。このため、データベースはすべての行をスキャンし、新しいパーティション式に基づいてこれらの行を再パーティション化します。このリクエストを実行した後のパーティション区切りは、以前の1日ではなく、10日になります。

  • パーティション式で更新可能なDATEまたはCURRENT_DATEの値を使用した場合は、しばらく時間が経過すると、RANGE_N関数に基づくパーティション式が廃れることがあります。このような場合にRANGE_N関数を指定するには十分な注意が必要です。調整が持つ影響を完全に理解し、DATE、CURRENT_DATE、またはCURRENT_TIMESTAMPの値を調整するたびに値が変わる可能性があることを完全に理解できた場合のみ、使用してください。

    たとえば、次のCREATE TABLEリクエストについて考えてみましょう。

         CREATE TABLE ppi (
           i INTEGER,
           j DATE)
         PRIMARY INDEX(i)
         PARTITION BY RANGE_N(j BETWEEN CURRENT_DATE
                                AND     DATE '2008-01-01'
                                EACH INTERVAL '1' MONTH);

    2008年1月1日よりも後にALTER TABLE TO CURRENTリクエストを使用してこのテーブルを調整すると、リクエストはアボートし、データベースはリクエスト側にエラーを返します。これは定義されている範囲がすべてnullであるためです。

    日付またはタイムスタンプの定数が有効であれば、パーティション式のどの場所にもDATE、CURRENT_DATE、またはCURRENT_TIMESTAMP関数を指定することができますが、これらの関数の指定には十分に注意する必要があります。

    たとえば、ALTER TABLE TO CURRENTリクエストを使用してパーティション式の中で新しく解釈されたDATE、CURRENT_DATE、またはCURRENT_TIMESTAMPの値での行の調整は、効率がよくないことがあります。これは、テーブルをスキャンして調整が必要な行を見つけるのに時間がかかることと、調整が必要な行を移動または削除するのに時間がかかることが原因です。

    パーティション全体の削除操作など、最適化のメリットがなく、テーブルのかなりの比率の行の調整が必要な場合、他の形式のパーティションの方が適していることが考えられます。

    以降のいくつかのトピックで説明する事例では、調整を効率よく行なう方法、および最適化できるようにする方法について示しています。