Skip to main content

This is documentation for Caché & Ensemble. See the InterSystems IRIS version of this content.Opens in a new tab

For information on migrating to InterSystems IRISOpens in a new tab, see Why Migrate to InterSystems IRIS?

テーブルの最適化

Caché SQL テーブルのパフォーマンスを最大化するために、いくつかの方法を実行できます。最適化は、このテーブルに対するクエリの実行に大きな効果をもたらす可能性があります。この章では、以下に示すパフォーマンス最適化の考慮事項について説明します。

  • ExtentSize、Selectivity、および BlockCount では、テーブルにデータを移入する前に、テーブル・データの見積もりを指定します。このメタデータは、今後のクエリを最適化するために使用されます。

  • テーブルのチューニング では、データが移入されているテーブル内の代表的なテーブル・データを分析します。これにより生成されたメタデータは、今後のクエリを最適化するために使用されます。

ExtentSize、Selectivity、および BlockCount

特定の SQL クエリを実行する最も効率的な方法をクエリ・オプティマイザが決定するときに、考慮される項目が 3 つあります。

  • ExtentSize は、クエリ内で使用されるテーブルごとの行数です。

  • Selectivity は、クエリで使用される列ごとに計算された個別値の割合です。

  • BlockCount は、クエリで使用される SQL マップごとのカウント数です。

クエリ・オプティマイザが正しい決定を下すためには、これらの値が正しく設定されていることが重要です。

  • これらの統計は、テーブルにデータを移入する前に、クラス (テーブル) の定義を行うときに明示的に設定できます。

  • テーブルに代表的なデータを移入したら、テーブル・チューニングを実行してこれらの統計を計算できます。

  • テーブル・チューニングを実行した後、明示的な値を指定して、計算された統計をオーバーライドすることもできます。

明示的に設定した統計と、テーブルのチューニングで生成された結果を比較できます。テーブルのチューニングで行った想定により、クエリ・オプティマイザの結果よりも適切でない結果が得られた場合は、テーブルのチューニングで生成された統計ではなく、明示的に設定した統計を使用してください。

スタジオのクラス編集ウィンドウに、クラスのソース・コードが表示されます。ソース・コードの末尾にはストレージ定義が表示されますが、この定義にはプロパティごとに ExtentSize クラスと Selectivity クラス (該当する場合は OutlierSelectivity クラスも) が含まれています。

ExtentSize

テーブルの ExtentSize 値は、そのテーブルに保存されている行数 (概数) を表します。

開発時には、ExtentSize の初期値を指定できます。ExtentSize を指定しない場合、既定値は 100,000 です。

通常、データを移入したときに予想されるこのテーブルのサイズを大まかに見積もります。正確な値である必要はありません。この値は、さまざまなテーブルのスキャンの相対コストを比較するときに使用します。関連するテーブル間の ExtentSize の相対値が正確な比率を表すようにすることが最も重要です (つまり、小さいテーブルの値は小さく、大きいテーブルの値は大きくする必要があります)。

  • CREATE TABLE には、以下の例に示すように、テーブル内の行数の予想値を指定するための %EXTENTSIZE パラメータ・キーワードが用意されています。

    CREATE TABLE Sample.DaysInAYear (%EXTENTSIZE 366, 
                                     MonthName VARCHAR(24),Day INTEGER,
                                     Holiday VARCHAR(24),ZodiacSign VARCHAR(24))
  • テーブルの永続クラス定義では、ストレージ定義内で ExtentSize パラメータを指定できます。

    <Storage name="Default">
    <Data name="MyClassDefaultData">
    ...
    <ExtentSize>200</ExtentSize>
    ...
    </Storage>
    
    
    

    この例では、MyClass クラスのストレージ定義を示しています。ここでは、ExtentSize に値 200 を指定しています。

テーブルが実際の (現実的な) データを持つ場合は、管理ポータルのテーブルのチューニング機能により、自動的に ExtentSize 値を計算して設定できます。詳細は、後述の "テーブルのチューニング" セクションを参照してください。

Selectivity (選択性)

Caché SQL テーブル (クラス) では、各列 (プロパティ) に Selectivity 値が関連付けられています。列の Selectivity 値は、標準的な列の値を検索するクエリの結果として返される、テーブル内の行の割合を示します。Selectivity は 1/D です。D は、フィールドの個別値の数です。

Selectivity は、ほぼ同じ数量の個別値に基づきます。例えば、Gender (性別) という列を持つテーブルがあり、その値が “M” (男性) と “F” (女性) にほぼ均等に分散しているとします。Gender 列の Selectivity 値は 50% になります。Street Name などのさらに特有なプロパティに対する Selectivity 値は、通常、小さい割合になります。

すべての値が同じであるフィールドの Selectivity は 100% です。一意として定義された (すべての値が異なる) フィールドの Selectivity は 1 です (1.0000% の Selectivity と混同しないでください)。

開発時には、テーブルのクラス定義の一部であるストレージ定義内に Selectivity パラメータを定義して、この値を設定することができます。

<Storage name="Default">
<Data name="MyClassDefaultData">
...
<Property name="Gender">
<Selectivity>50%</Selectivity>
</Property>
...
</Storage>

スタジオでクラスのストレージ定義を確認するには、[ビュー] メニューから [ストレージの表示] を選択します。すると、クラスのソース・コードの下部にストレージが表示されます。

通常は、アプリケーションで使用される場合に予測される Selectivity 値の概数を指定します。ExtentSize と同様に、正確な値である必要はありません。ほとんどの Caché のデータ型クラスでは、Selectivity に妥当な既定値が指定されます。

また、$SYSTEM.SQL.SetFieldSelectivity()Opens in a new tab メソッドを使用して、特定のフィールド (プロパティ) の Selectivity 値を設定することもできます。

テーブルに実際の (現実的な) データが含まれている場合は、管理ポータルのテーブル・チューニング機能を使用して、その Selectivity 値を自動的に計算し、設定できます。テーブル・チューニングでは、他のどの値よりもはるかに多く存在する値である異常値がフィールドにあるかどうかが確認されます。異常値がある場合、テーブル・チューニングでは、別の Outlier Selectivity の割合が計算され、その異常値の割合に基づいて Selectivity が計算されます。異常値の割合によって、Selectivity 値が著しく変わることがあります。

BlockCount

永続クラスをコンパイルする際、クラス・コンパイラは、ExtentSize とプロパティ定義に基づいて、各 SQL マップで使用されるマップ・ブロックの概数を計算します。これらの BlockCount 値は、テーブル・チューニング機能[マップ・ブロック・カウント] タブで表示できます。この BlockCount は、テーブル・チューニングでは Estimated by class compiler として識別されます。ExtentSize を変更した場合、その変更が BlockCount 値に反映されていることを確認するには、SQL の [テーブルチューニング] ウィンドウを閉じてから、開き直す必要があります。

テーブル・チューニングを実行すると、SQL マップごとの実際のブロック・カウントが測定されます。特別な指定がない場合、テーブルのチューニングの測定値により、クラス・コンパイラの概算値が置き換えられます。テーブル・チューニングで測定されたこれらの値は、指定した BlockCount 値と区別するために、クラス定義では負の整数として表されます。詳細は、以下の例を参照してください。

<SQLMap name="IDKEY">
 <BlockCount>-4</BlockCount>
</SQLMap>

テーブル・チューニングで測定された値は、テーブル・チューニングでは正の整数として表され、Measured by TuneTable として識別されます。

クラス定義内では、明示的に BlockCount の値を定義できます。以下の例に示すように、ブロック・カウントを明示的に正の整数として指定できます。

<SQLMap name="IDKEY">
 <BlockCount>12</BlockCount>
</SQLMap>

クラスを定義するときには、マップについての BlockCount の定義を省略するか、BlockCount を明示的に正の整数として指定するか、BlockCount を明示的に NULL として定義できます。

  • BlockCount を指定しない場合、または BlockCount を 0 として指定した場合は、クラス・コンパイラによってブロック・カウントが試算されます。テーブル・チューニングを実行すると、クラス・コンパイラによって試算された値が置換されます。

  • 正の整数の BlockCount を明示的に指定した場合、テーブル・チューニングを実行しても、その明示的な BlockCount 値は置換されません。明示的なクラス定義のブロック・カウント値は、テーブル・チューニングでは正の整数として表され、Defined in class definition として識別されます。これらのブロック・カウント値は、テーブル・チューニングをその後実行しても変更されません。

  • NULL の BlockCount を明示的に指定した場合、SQL マップは、クラス・コンパイラによって試算された BlockCount 値を使用します。BlockCount はクラス定義で “定義” されているので、テーブル・チューニングを実行しても、試算されたこの BlockCount 値は置換されません。

すべての Caché SQL マップ・ブロックのサイズは 2048 バイト (2KB) です。

以下の状況では、テーブルのチューニングによる BlockCount の測定は行われません。

  • テーブルが、配列コレクションまたはリスト・コレクションで投影された子テーブルの場合。このような子テーブルに対する BlockCount 値は、親テーブルのデータ・マップに対する BlockCount と同じになります。

  • グローバル・マップが、リモート・グローバル (別のネームスペース内のグローバル) の場合。その代わりに、クラス・コンパイル時に使用された見積もり BlockCount が使用されます。

テーブルのチューニング

テーブル・チューニングは、テーブル内のデータを検証し、ExtentSize (テーブル内の行の数)、各フィールドの個別値の相対的な分散、および平均フィールド・サイズ (各フィールドの値の平均長) に関する統計を返すユーティリティです。また、SQL マップごとの BlockCount も生成します。テーブルのチューニングがこの情報を使用して、テーブルとその各フィールドに関連付けられているメタデータを更新することを指定できます。その後、クエリ・オプティマイザは、これらの統計を使用して、クエリの最も効率的な実行プランを特定できます。

外部テーブルでテーブル・チューニングを使用する場合は、ExtentSize のみが計算されます。テーブル・チューニングでは、外部テーブルについてフィールドの Selectivity 値、平均フィールド・サイズ、またはマップの BlockCount 値を計算することはできません。

テーブル・チューニングの実行時

各テーブルに対してテーブル・チューニングを実行する前に、そのテーブルに代表的な数量の実データを移入しておく必要があります。一般に、テーブル・チューニングは、アプリケーション開発の最終段階として、データを “実動環境” に移す前の 1 回しか実行する必要はありません。テーブル・チューニングはメンテナンス・ユーティリティではありません。実動データで定期的には実行しないでください

Note:

テーブル・チューニングによって SQL のパフォーマンスが低下することはまれです。テーブル・チューニングは実動データに対して実行できますが、プロダクション・システム上ではなく、テスト・システム上で実データを使用して実行することをお勧めします。

通常は、以下のように、現在のデータの特性が大幅に変わった場合を除き、テーブル・データが追加、変更、または削除されたときにテーブル・チューニングを再実行しないでください。

  • 相対的なテーブル・サイズ:テーブル・チューニングは、データの代表的なサブセットを分析することを前提にしています。代表的なサブセットであれば、このサブセットはデータ・セット全体のごぐ一部でかまいません。結合またはその他のリレーションシップに関係するテーブルの ExtentSize が相対的にほぼ同等なサイズを維持している場合は、テーブル内の行数が変わっても、テーブル・チューニングでは引き続き妥当な結果が得られます。結合テーブル間の比の桁数が変わる場合は、ExtentSize を更新する必要があります。SQL オプティマイザは、テーブル結合順序を最適化するときに ExtentSize を使用するため、これは JOIN 文で重要です。原則として、クエリで指定された結合順序に関係なく、小さいテーブルは大きいテーブルより前に結合されます。したがって、tableA と tableB の行の比率が 1000:2000 から 10000:2000 に変わった場合は、1 つ以上のテーブルに対してテーブル・チューニングを再実行する必要がありますが、2100:4000 に変わってもその必要はありません。

  • 均等な値の分散:テーブルのチューニングは、各データ値が均等に分散することを前提にしています。異常値を検出した場合は、異常値以外の各データ値が均等に分散することを前提とします。テーブルのチューニングでは、各フィールドの現在のデータ値を分析することで、Selectivity を確定します。実データにおける均等な分散は常に概算です。個別データ値の数とそれらの相対的な分散の変動が通常の範囲であれば、テーブル・チューニングを再実行する必要はありません。ただし、フィールドで使用される可能性がある値の数 (レコードに対する個別値の比率) や、1 つのフィールド値が全体に占める割合が大幅に変わった場合は、Selectivity が正確でなくなる可能性があります。1 つのフィールド値を持つレコードの割合が著しく変わると、テーブル・チューニングで異常値が指定されたり、異常値の指定が解除されて、計算された Selectivity が大幅に変わることがあります。1 つのフィールドの Selectivity が、実際のデータ値の分散を反映しなくなった場合には、テーブルのチューニングを再実行する必要があります。

  • Caché の大幅なアップグレード、または新規サイトでのインストールでは、テーブル・チューニングの再実行が必要になる場合があります。

テーブルのチューニングの実行

テーブルのチューニングは、管理ポータルを使用するか、$SYSTEM.SQL.TuneTable() メソッドを呼び出すことによって使用できます。テーブル・チューニングを実行する前に、テーブルにデータが格納されている必要があります。

テーブルのチューニング機能を実行した後、結果として得られる ExtentSize および Selectivity の値は、クラスのストレージ定義に保存されます。スタジオでストレージ定義を確認するには、[ビュー] メニューから [ストレージの表示] を選択します。すると、クラスのソース・コードの下部にストレージが表示されます。

管理ポータルからのテーブル・チューニング

管理ポータルからテーブル・チューニングを実行するには、以下の手順を実行します。

  1. [システム・エクスプローラ][SQL] (システム, SQL) を選択します。ページ上部の [切り替え] オプションをクリックしてネームスペースを選択し、表示されたリストからネームスペースを選択します  (ユーザごとに管理ポータルの既定ネームスペースを設定できます)。

  2. 画面の左側にあるドロップダウン・リストから [スキーマ] を選択するか、[フィルタ] を使用します。[スキーマ] および [フィルタ] の使用方法の詳細は、このドキュメントの “管理ポータルの SQL インタフェースの使用法” の "SQL スキーマの参照" を参照してください。

  3. 以下のいずれかを行います。

    • 1 つのテーブルのチューニング : [テーブル] カテゴリを展開し、リストからテーブルを選択します。テーブルを選択したら、[アクション] ドロップダウン・リストをクリックし、[テーブル・チューニング情報] を選択します。テーブルの現在のエクステント・サイズおよび選択性に関する情報が表示されます。テーブル・チューニングを実行したことがない場合は、エクステント・サイズ = 100000 が表示され、選択性、異常値の選択性、異常値、または平均フィールド・サイズに関する情報は表示されません (選択性が 1 の ID 以外)。また、マップ・ブロック・カウントに関する情報は Estimated by class compiler として示されます。

      [選択性] タブから、[テーブルチューニング] ボタンを選択します。テーブルに対してテーブル・チューニングが実行され、テーブル内のデータに基づいてエクステント・サイズ選択性異常値の選択性異常値、および平均フィールド・サイズの値が計算されます。マップ・ブロック・カウントに関する情報は、Measured by Tune Table として示されます。

    • スキーマ内のすべてのテーブルのチューニング : [アクション] ドロップダウン・リストをクリックし、[スキーマ内の全テーブルをチューニング] を選択します。[テーブルチューニング] ボックスが表示されます。[完了] ボタンを選択して、スキーマ内のすべてのテーブルに対してテーブル・チューニングを実行します。テーブル・チューニングが完了すると、このボックスに [完了] ボタンが表示されます。[完了] を選択して、[テーブルチューニング] ボックスを終了します。

SQL の [テーブルチューニング] ウィンドウには、[選択性][マップ・ブロック・カウント] という 2 つのタブがあります。これらのタブには、テーブル・チューニングによって生成された現在の値が表示されます。これらのタブを使用して、テーブル・チューニングによって生成された値とは異なる値を手動で設定することもできます。

[選択性] タブには以下のフィールドがあります。

  • [現在のテーブルエクステントサイズ]。このフィールドには、異なるテーブル・エクステント・サイズを入力するための [編集] ボタンがあります。

  • [クラスを最新状態に保つ] チェック・ボックス。テーブル・チューニング、[テーブルチューニング] インタフェースでユーザが入力した値、またはテーブル・チューニング・メソッドによって生成された統計に対する変更はすべて、即座にクラス定義に反映されます。

    • このチェック・ボックスにチェックが付いている場合 (はい)、変更されたクラス定義が自動的にコンパイルされ、最新状態に維持されます。この永続クラス (テーブル) を使用するクエリ・キャッシュは削除されません。これは、実動システムで統計を変更する場合に推奨されるオプションです。

    • このチェック・ボックスにチェックが付いていない場合 (いいえ)、変更されたクラス定義には、古くなっているためにコンパイルが必要であるというフラグが設定されます。この永続クラス (テーブル) を使用するクエリ・キャッシュは即座に削除されます。既定では、チェックは付いていません。

  • [フィールド名]、[選択性]、[メモ]、[異常値の選択性]、[異常値]、および [平均フィールド・サイズ] の列がある [フィールド] テーブル。[フィールド] テーブルの見出しをクリックして、その列の値でソートすることができます。[フィールド] テーブルの行をクリックして、そのフィールドの選択性、異常値の選択性、異常値、および平均フィールド・サイズの値を手動で設定できます。

[ブロックカウントのマップ] タブには以下のフィールドがあります。

  • [SQL マップ名]、[ブロックカウント]、および [ブロックのカウント元]の列がある [マップ名] テーブル。個々のマップ名をクリックして、そのマップ名のブロック・カウント値を手動で設定できます。

[選択性] タブから、[テーブルチューニング] ボタンをクリックして、このテーブルに対してテーブル・チューニングを実行できます。

メソッドを使用したテーブル・チューニング

$SYSTEM.SQL.TuneTable()Opens in a new tab メソッドを使用して、テーブルに対してテーブル・チューニング機能を実行することができます。詳細は、以下の例を参照してください。

  ZNSPACE "Samples"
  DO $SYSTEM.SQL.TuneTable("Sample.Person",0,1)

この例の 2 番目のパラメータは、このテーブルのチューニングによって呼び出された Calculated が、テーブルの現在の ExtentSizeSelectivity の値を更新しないことを指定します。3 番目のパラメータは、テーブルのチューニングの結果をターミナルに表示することを指定します。

TuneTable() メソッドを使用すると、以下のエラー・メッセージが生成されることがあります。

  • 存在しないテーブル:DO $SYSTEM.SQL.TuneTable("NoSuchTable",0,1)

    No such table 'SQLUser.NoSuchTable'

  • ビュー:DO $SYSTEM.SQL.TuneTable("MyView",0,1)

    'SQLUser.MyView' is a view, not a table.No tuning will be performed.

$SYSTEM.SQL.TuneSchema()Opens in a new tab メソッドを使用して、スキーマのすべてのテーブルに対してテーブル・チューニング機能を実行することができます。

実動データでのテーブル・チューニングの実行

テーブル・チューニングは、実動システム (テーブル・データがアクティブにアクセスおよび変更されているシステム) 上で実行できます。テーブル・チューニングの実行は、パフォーマンスに影響を与えます。

[クラスを最新状態に保つ] チェック・ボックスのチェックを外して実動システムでテーブル・チューニングを実行するか、KeepUpToDate=0 を指定して TuneTable() メソッドを実行すると、使用中のクエリ・キャッシュが自動的に削除される可能性があるため、アプリケーション・エラーが発生することがあります。テーブル・チューニングの実行後にクラスが期限切れとして扱われないようにするには、[クラスを最新状態に保つ] チェック・ボックスにチェックを付けるか、$SYSTEM.SQL.TuneTable()Opens in a new tab で KeepClassUpToDate=1 パラメータを指定する必要があります。

テーブル・チューニングの実行後、クエリ・オプティマイザで新しいテーブル・チューニング値が使用されるように、クエリ・キャッシュを削除 (手動で、またはクラスのリコンパイルによって) する必要があります。

エクステントサイズと行カウント

管理ポータルからテーブル・チューニング機能を実行する場合は、ExtentSize が、現在テーブル内にある行の実際の数になります。既定では、TuneTable() メソッドは、ExtentSize として実際の行数も使用します。テーブルに多数の行が含まれる場合は、より少ない行数で分析を実行することをお勧めします。TuneTable() メソッドを実行する場合は、以下の例に示すように、オプションで異なる ExtentSize を指定できます。

  ZNSPACE "Samples"
  DO $SYSTEM.SQL.TuneTable("Sample.Person",0,1,,,,,50)

このオプションを使用すると、多数の行が含まれるテーブルに対して TuneTable() を実行したときのパフォーマンスが向上します。ExtentSize をテーブル内の実際の行数よりも少なく指定する場合、この ExtentSize の数値は、代表的なデータのサンプリングに十分な大きさにする必要があります。

指定された ExtentSize は、実際の行数より少なくても多くてもかまいません。ただし、ExtentSize は、現在のテーブル・データの実際の行数を大幅に超えてはいけません。ExtentSize を指定すると、TuneTable() は、その行数に応じた行 ID を推定して、サンプリングを実行します。ExtentSize が実際の行数を大幅に超えていると、サンプリングされる行 ID の大部分は実際の行データに対応しなくなります。この場合は、フィールドの選択性が計算できなくなります。その代わりに、TuneTable() は、指定された ExtentSize を CALCULATED ExtentSize とし、より小さい数を SAMPLESIZE としてリストします。TuneTable() は存在しない計算値に対して <Not Specified> を返します。

TuneTable() メソッドに SamplePercent を指定できます。これにより、サンプリングするための ExtentSize の割合が指定されます。SamplePercent は、既定値の "" (NULL 文字列) となります。この既定値では、データは以下のようにサンプリングされます。

  • ExtentSize < 1000 の場合:SamplePercent="" では、エクステント・サイズ全体が使用されます。例えば、ExtentSize が 600 の場合は、600 件のサンプルが使用されます。

  • ExtentSize >= 1000 の場合:SamplePercent="" では、3*sqrt(ExtentSize) が使用されます。例えば、ExtentSize が 10,000 の場合は、300 件のサンプルが使用されます。

0 の ExtentSize を設定できます。これは、データは入力されないが、クエリの結合などその他の目的で使用される予定のテーブルがある場合に適切です。ExtentSize を 0 に設定すると、Caché は各フィールドの選択性を 100% として設定し、各フィールドの平均フィールド・サイズを 0 として設定します。

CALCSELECTIVITY パラメータと、Selectivity 計算の抑止

特定のプロパティの Selectivity を、テーブルのチューニング機能で計算しないようにすることが必要な場合があります。Selectivity が計算されないようにするには、プロパティの CALCSELECTIVITY パラメータを 0 に設定します (既定値は 1)。CALCSELECTIVITY は、スタジオの [新規プロパティウィザード][プロパティパラメータ] ページで設定できます。また、インスペクタのプロパティ・パラメータのリストでも設定できます (このパラメータを表示するには、プロパティ・パラメータ・リストを一度縮小してから再展開することが必要な場合があります)。

例えば、すべての行に含まれる値が 1 つのみ (Selectivity=100%) だとわかっているフィールドには、CALCSELECTIVITY=0 を指定する必要があります (そのフィールドにインデックスが作成されていない場合)。

Selectivity と Outlier Selectivity

テーブルのチューニングでは、Selectivity (選択性) が、プロパティ (フィールド) の値ごとに割合として計算されます。これは、データをサンプリングすることで行われるため、Selectivity は常に推定値になります (正確な値ではありません)。Selectivity は、すべてのプロパティ値が均一である (または均一になる) という仮定に基づきます。これは、ほとんどのデータに対して合理的な仮定です。例えば、一般的な人口テーブルのほとんどのデータ値は典型的な値になります。特定の誕生日はデータの約 0.27% (365 分の 1) で出現し、男性と女性はおよそ半々 (50%) の存在になります。一意として定義されたフィールドは、1 の Selectivity になります (1.0000 (1%) の Selectivity と混同しないようにしてください)。Selectivity の割合は、ほとんどのプロパティに対して十分に必要を満たします。

いくつかのプロパティに対して、テーブルのチューニングでは Outlier Selectivity (異常値の選択性) も計算します。これは、サンプル内で、その他のデータ値よりも頻出する 1 つのプロパティ値の割合です。テーブルのチューニングは、あるデータ値の頻度とその他のデータ値の頻度に大幅な差があるときにのみ、Outlier Selectivity を返します。テーブル・チューニングで返される異常値は、データ値の分散に関係なく、多くても 1 つのテーブルについて 1 つです。異常値が選択されると、テーブルのチューニングはこの値を Outlier Value として表示します。NULL は <Null> として表示されます。

テーブル・チューニングで異常値の選択性が返される場合、通常の選択性は、依然として全行のうちの異常でない各データ値の割合となります。例えば、異常値の選択性が 80% で通常の選択性が 1% の場合、異常値のほかに、約 20 ((1-.80)/.01) の非異常値が見つかることが予想できます。

最も一般的な Outlier Selectivity の例として、NULL を許可するプロパティが挙げられます。あるプロパティに対する NULL のレコード数が、そのプロパティに対する特定のデータ値を持つレコード数を大幅に上回ると、NULL が異常値になります。以下に、FavoriteColors フィールドの Selectivity と Outlier Selectivity を示します。

SELECTIVITY of FIELD FavoriteColors
   CURRENT =     1.8966%
   CALCULATED =  1.4405%
   CURRENT OUTLIER = 45.0000%, VALUE = <Null>
   CALCULATED OUTLIER = 39.5000%, VALUE = <Null> 

フィールドに 1 つの個別値のみが含まれている (すべての行の値が同じ) 場合、Selectivity は 100% です。Selectivity が 100% の値は、異常値とは見なされません。通常、テーブル・チューニングは Selectivity と Outlier Selectivity の値を確定するためにデータをサンプリングして予測を立てますが、これでは 1 つの値のみが存在することを立証するには不十分です。すべての行を調査する必要があります。そのため、テーブル・チューニングは、フィールドにインデックスが作成されている場合、そのフィールドがインデックスの最初のフィールドの場合、およびフィールドとインデックスの照合タイプが同じ場合にのみ、この種のフィールドを認識できます。上記のインデックスがフィールドに作成されていない場合は、手動で 100% の Selectivity を指定し、Outlier Selectivity を削除して、CALCSELECTIVITY=0 を設定します。これにより、テーブル・チューニングが選択性を計算したり、この値を異常値として指定したりしないようにします。

これらの SelectivityOutlier Selectivity、および Outlier Value の計算値を変更するには、テーブルのチューニングの表示から個々のフィールドを選択します。これにより、表示の右側の [詳細] 領域に、そのフィールドに対するこれらの値が表示されます。SelectivityOutlier Selectivity、および Outlier Value を、予期される完全なデータ・セットにより適した値に変更することができます。

  • Selectivity は、パーセント (%) 記号を含む行のパーセント、または行の整数 (パーセント記号なし) のどちらかで指定できます。行の整数として指定する場合、Caché はエクステント・サイズを使用して Selectivity のパーセントを計算します。

  • 以前に異常値のなかったフィールドに Outlier Selectivity および Outlier Value を指定できます。パーセント (%) 記号を持つパーセントとして Outlier Selectivity を指定します。Outlier Selectivity のみを指定した場合、テーブルのチューニングでは Outlier Value が <Null> であると仮定されます。 Outlier Value のみを指定した場合、テーブルのチューニングでは Outlier Selectivity を指定しない限りこの値を保存しません。

異常値の最適化

既定では、クエリ・オプティマイザはクエリが異常値を選択することはないと想定します。例えば、一般にクエリは特定のフィールド値を選択して、データベースから少数のレコードを返しますが、そのフィールド値が異常値である場合は多数のレコードを返します。クエリ・オプティマイザでは、Outlier Selectivity を考慮するよう要求するいくつかの操作を実行しない限り、クエリ・プランの作成に常に Selectivity が使用されます。

異常値の選択に基づいてクエリの最適化を調整するために実行できるいくつかの操作があります。

  • Outlier Value が <null> の場合、クエリの WHERE 節のフィールドに IS NULL または IS NOT NULL 条件を指定します。これにより、クエリの作成時にクエリ・オプティマイザで Outlier Selectivity が使用されるようになります。

  • Outlier Value がデータ値の場合、クエリ・オプティマイザは選択対象のフィールド値が異常値ではないと想定します。例えば、Massachusetts に拠点を置く会社の従業員レコードには、Office_State フィールドに 'MA' (Massachusetts) の異常値が含まれる場合があります。オプティマイザは、データベース内の大半のレコードを返すことになる 'MA' をクエリで選択することはないと想定します。ただし、異常値を選択するクエリを作成する場合は、それをオプティマイザに知らせるために、その異常値を二重括弧で囲みます。フィールドでクエリを実行する際、WHERE Office_State=(('MA')) のように WHERE 節を指定します。この方法によって、リテラル置換が抑制され、クエリ・プランの作成時にオプティマイザが Outlier Selectivity を使用するように強制します。この構文はダイナミック SQL クエリと、Caché の外部で記述され ODBC/JDBC を使用して指定されるクエリに必要です。クラス・クエリ、埋め込み SQL クエリ、またはビューにあるクエリには必要ありません。詳細は、"WHERE 節" のリファレンス・ページを参照してください。

  • [異常値としてクエリにバイアスをかける] 構成オプションを使用しないでください。このチェック・ボックスのチェックは外したままにします。

[メモ] 列

管理ポータルの [テーブル・チューニング情報] オプションでは、フィールドごとに [メモ] 列が表示されます。このフィールドの値はシステムによって定義され、変更することはできません。以下の値があります。

  • RowID field : テーブルには、システムによって定義される RowID が 1 つあります。通常、その名前は ID ですが、システムによって割り当てられた別の名前を持つ場合もあります。その値はすべて (定義上は) 一意であるため、選択性は常に 1 です。クラス定義に SqlRowIdPrivate が含まれている場合、[メモ] 列の値は RowID field, Hidden field です。

  • Hidden field : 非表示フィールドはプライベートとして定義され、SELECT * によって表示されることはありません。既定では、CREATE TABLE では RowID フィールドは非表示として定義されます。%PUBLICROWID キーワードを指定すると、RowID を非表示でなく、パブリックとして定義できます。既定では、永続クラス定義によって定義されたテーブルでは、RowID は非表示でないとして定義されます。SqlRowIdPrivate を指定すると、RowID を非表示およびプライベートとして定義できます。コンテナ・フィールドは、非表示として定義されます。

  • Stream fieldストリーム・データ型 (文字ストリーム (CLOB) またはバイナリ・ストリーム (BLOB)) で定義されたフィールドを示します。ストリーム・ファイルには平均フィールド・サイズはありません。

  • Parent reference field親テーブルを参照するフィールドです。

IDENTITY フィールド、ROWVERSION フィールド、SERIAL フィールド、または UNIQUEIDENTIFIER (GUID) フィールドは、[メモ] 列では識別されません

平均フィールド・サイズ

テーブルのチューニングを実行すると、現在のテーブル・データ・セットに基づいて、すべての非ストリーム・フィールドの平均フィールド・サイズ (文字数) が計算されます。これは、(特に明記されていない限り) 小数点以下 2 桁に丸められた AVG($LENGTH(field)) と同じです。予期されるフィールド・データの平均サイズを反映するよう、個々のフィールドについてこの平均サイズを変更できます。

  • NULL:$LENGTH 関数は NULL フィールドを 0 の長さを持つものとして処理するため、NULL フィールドは長さ 0 で平均化されます。これにより、平均フィールド・サイズが 1 文字未満になる場合があります。

  • 空の列:列にデータが含まれていない (すべての行のフィールド値がない) 場合、平均フィールド・サイズの値は 0 ではなく、1 です。AVG($LENGTH(field)) は、データが含まれていない列については 0 です。

  • ExtentSize=0:ExtentSize を 0 に設定すると、すべてのフィールドの平均フィールド・サイズは 0 にリセットされます。

  • 論理フィールド値:平均フィールド・サイズは、常にフィールドの論理 (内部) 値に基づいて計算されます。

  • リスト・フィールド:Caché リスト・フィールドは、論理 (内部) エンコード値に基づいて計算されます。このエンコードされた長さは、リスト内の要素の合計の長さより長くなります。

  • コンテナ・フィールド:コンテナ・フィールドは、コレクション・オブジェクトの合計の長さより大きくなります。例えば、Sample.Person で、Home コンテナ・フィールドの平均フィールド・サイズは、Home_Street、Home_City、Home_State、および Home_Zip の平均フィールド・サイズの合計より大きくなります。 詳細は、"Caché オブジェクトの使用法" の “コレクション・プロパティの SQL プロジェクションの制御” を参照してください。

  • ストリーム・フィールド:ストリーム・フィールドには平均フィールド・サイズはありません。

プロパティ・パラメータ CALCSELECTIVITY がプロパティ/フィールドで 0 に設定されると、テーブルのチューニングでそのプロパティ/フィールドの平均フィールド・サイズが計算されません。

テーブルのチューニングの表示から個々のフィールドを選択することで、平均フィールド・サイズの計算値を変更できます。これにより、表示の右側の [詳細] 領域に、そのフィールドの値が表示されます。平均フィールド・サイズは、予期される完全なデータ・セットにより適した値に変更できます。この値の設定時にテーブルのチューニングで検証が実行されないため、フィールドがストリーム・フィールドではないこと、および指定した値が最大フィールド・サイズを超えない (MaxLen) ことを確認する必要があります。

平均フィールド・サイズは、管理ポータルの [カタログの詳細] タブの [フィールド] オプション・テーブルにも表示されます。平均フィールド・サイズの値を表示するには、[フィールド] オプション・テーブルでテーブルのチューニングが実行されている必要があります。詳細は、このドキュメントの “管理ポータルの SQL インタフェースの使用法” の章の "[カタログの詳細] タブ" のセクションを参照してください。

[BlockCount のマップ] タブ

テーブルのチューニングの [BlockCount のマップ] タブには、[SQL マップ名][BlockCount] (正の整数として)、および [BlockCount のソース] が表示されます。[BlockCount のソース] は、Defined in class definitionEstimated by class compiler、または Measured by TuneTable のいずれかになります。テーブルのチューニングを実行すると、Estimated by class compilerMeasured by TuneTable に変わります。Defined in class definition の値には影響しません。

テーブルのチューニングの表示から個々の SQL マップ名フィールドを選択することで、BlockCount の計算値を変更できます。これにより、表示の右側の [詳細] 領域にあるフィールドに値が表示されます。BlockCount は、予期される完全なデータ・セットにより適した値に変更できます。この値の設定時にテーブルのチューニングで検証が実行されないため、ブロックカウントが有効な値であることを確認する必要があります。BlockCount を変更すると、[BlockCount のソース]Defined in class definition に変更されます。詳細は、このドキュメントの "BlockCount" のセクションを参照してください。

テーブルのチューニングの統計のエクスポートと再インポート

テーブル・チューニング統計をテーブルまたはテーブルのグループからエクスポートし、それらのテーブル・チューニング統計をテーブルまたはテーブルのグループにインポートできます。以下に示す 3 つの状況で、このエクスポート/インポートの実行が必要になることがあります (わかりやすくするために、1 つのテーブルの統計のエクスポート/インポートについて説明します。実際には、多くの場合、相互に関連する複数のテーブルの統計のエクスポート/インポートが実行されます)。

  • プロダクション・システムをモデル化する場合 : 実際のデータを使用してプロダクション・テーブルを完全に生成し、テーブル・チューニングを使用して最適化します。テスト環境で、同じテーブル定義でテーブルを作成しますが、はるかに少ないデータを使用します。テーブル・チューニング統計をプロダクション・テーブルからエクスポートし、テスト・テーブルにインポートすることにより、テスト・テーブルでプロダクション・テーブルの最適化をモデル化できます。

  • プロダクション・システムを複製する場合 : 実際のデータを使用してプロダクション・テーブルを完全に生成し、テーブル・チューニングを使用して最適化します。同じテーブル定義の 2 つ目のプロダクション・テーブルを作成します。例えば、プロダクション環境とそのバックアップ環境や、同一のテーブル定義を使用する複数のテーブル (各テーブルに、例えば、異なる病院の患者レコードが格納されている) などがあります。テーブル・チューニング統計を最初のテーブルからエクスポートし、2 つ目のテーブルにインポートすることにより、テーブル・チューニングをもう一度実行したり、2 つ目のテーブルに代表的なデータが移入されるまで待つというオーバーヘッドを伴わずに、最初のテーブルと同じ最適化を 2 つ目のテーブルに適用できます。

  • 以前の統計セットに戻す場合 : テーブル・チューニングを実行したり、明示的に統計を設定したりすることにより、テーブルの最適化統計を作成します。これらの統計をエクスポートすることにより、それらを保持したまま、他の統計設定を試すことができます。最適な統計セットを特定したら、それらをテーブルにインポートして戻すことができます。

テーブルのチューニングの統計は、$SYSTEM.SQL.ExportTuneStats()Opens in a new tab メソッドを使用して、XML ファイルにエクスポートできます。このメソッドでは、以下の例に示すように、1 つのネームスペース内の 1 つのテーブル、複数のテーブル、またはすべてのテーブルについて、テーブルのチューニングの統計をエクスポートできます。

  DO $SYSTEM.SQL.ExportTuneStats("C:\AllStats.xml")
  /*  Exports TuneTable Statistics for all schemas/tables in the current namespace */
  DO $SYSTEM.SQL.ExportTuneStats("C:\SampleStats.xml","Sample")
  /*  Exports TuneTable Statistics for all tables in the Sample schema */
  DO $SYSTEM.SQL.ExportTuneStats("C:\SamplePStats.xml","Sample","P*")
  /*  Exports TuneTable Statistics for all tables beginning with the letter "P" in the Sample schema */
  DO $SYSTEM.SQL.ExportTuneStats("C:\SamplePersonStats.xml","Sample","Person")
  /*  Exports TuneTable Statistics for the Sample.Person table */

ExportTuneStats() を使用してエクスポートされたテーブルのチューニングの統計は、$SYSTEM.SQL.ImportTuneStats()Opens in a new tab メソッドを使用して再インポートできます。

ImportTuneStats() には、KeepClassUpToDate ブーリアン・オプションがあります。TRUE (および update が TRUE) の場合、ImportTuneStats() は、新しい EXTENTSIZE 値と SELECTIVITY 値でクラス定義を更新しますが、そのクラス定義は最新状態として維持されます。ただし、多くの場合、テーブルのチューニング後には、クラスを再コンパイルすることをお勧めします。そうすることで、クラス定義内のクエリが再コンパイルされ、SQL クエリ・オプティマイザは更新されたデータ統計を使用できるようになります。既定値は FALSE (0) です。クラスが配置される場合、クラス定義は更新されません。

ImportTuneStats() には、ClearCurrentStats ブーリアン・オプションがあります。TRUE の場合、ImportTuneStats() は、統計をインポートする前に既存のテーブルから以前の EXTENTSIZE、SELECTIVITY、BLOCKCOUNT、および他のテーブル・チューニング統計を消去します。これは、インポート・ファイルで指定されていないテーブル統計を、テーブルの永続クラスで定義されたままにするのではなく完全に消去する場合に使用できます。既定値は FALSE (0) です。

ImportTuneStats() は、対応するテーブルが見つからないときには、そのテーブルをスキップし、インポート・ファイル内でその次に指定されているテーブルに処理を進めます。テーブルが見つかったものの、一部のフィールドが見つからないときには、それらのフィールドが単にスキップされます。

クラス・ストレージ定義内のマップの BlockCount は継承できません。BlockCount は、マップが生成されたクラスのストレージ定義内にのみ現れます。ImportTuneStats() では、投影されたテーブルの BlockCount メタデータのみが設定され、クラス・ストレージの BlockCount メタデータは設定されせん (マップがスーパークラス内で生成された場合)。

FeedbackOpens in a new tab