ANALYZE — データベースに関する統計を収集する
ANALYZE [ (option[, ...] ) ] [table_and_columns[, ...] ] ANALYZE [ VERBOSE ] [table_and_columns[, ...] ]optionには以下のいずれかが入ります。 VERBOSE [boolean] SKIP_LOCKED [boolean] BUFFER_USAGE_LIMITsizeまた、table_and_columnsは以下の通りです。table_name[ (column_name[, ...] ) ]
ANALYZEはデータベース内のテーブルの内容に関する統計情報を収集し、その結果をpg_statisticシステムカタログに保存します。
問い合わせプランナが最も効率の良い問い合わせの実行計画を決定する際、この統計情報が使用されます。
table_and_columnsリストがない場合、ANALYZEは現在のデータベース内で現在のユーザが解析する権限のあるすべてのテーブルとマテリアライズドビューを処理します。
リストがある場合、ANALYZEは指定されたテーブルのみを処理します。
さらにテーブルの列名のリストを与え、その列の統計情報のみを収集することも可能です。
オプションリストが括弧で括られていた場合、オプションは任意の順序で書けます。 括弧付きの構文はPostgreSQL 11で追加されました。 括弧のない構文は廃止予定です。
VERBOSE進行状況の表示を有効にします。
SKIP_LOCKED
リレーション上で動作を開始する時に、ANALYZEは衝突しているロックが解放されるのを待たないことを指定します。リレーションを待つことなく即時にロックできない場合、そのリレーションは飛ばされます。
このオプションを指定しても、リレーションのインデックスを開く時、パーティションやテーブル継承の子、ある種類の外部テーブルからサンプル行を取得する時には、ANALYZEがブロックするかもしれないことに注意してください。
また、通常ANALYZEは指定されたパーティションテーブルのパーティションをすべて処理しますが、このオプションによりANALYZEは、パーティションテーブル上に衝突するロックがあれば、パーティションをすべてスキップします。
BUFFER_USAGE_LIMIT
ANALYZEのバッファアクセスストラテジリングバッファサイズを指定します。
このサイズは、このストラテジのパートとして再利用される共有バッファの数を計算するために使用されます。
0はバッファアクセスストラテジの使用を無効にします。
このオプションが指定されていない場合、ANALYZEはvacuum_buffer_usage_limitの値を使用します。
設定を高くするとANALYZEの実行速度が速くなりますが、設定が大き過ぎると、とても多くの他の有用なページが共有バッファから追い出されてしまう可能性があります。
最小値は128 kBで、最大値は16 GBです。
boolean
選択したオプションをオンにするかオフにするか指定します。
オプションを有効にする場合にはTRUE、ONまたは1と書くことができ、無効にする場合にはFALSE、OFFまたは0と書くことができます。
booleanの値は省略することもでき、その場合にはTRUEとみなされます。
size
メモリの量をキロバイト単位で指定します。
サイズは、数値のサイズに続いて、B(バイト)、kB(キロバイト)、MB(メガバイト)、GB(ギガバイト)またはTB(テラバイト)のいずれか1つのメモリ単位を含む文字列として指定することもできます。
table_name解析の対象とするテーブルの名前です(スキーマ修飾名も可)。 省略された場合、現在のデータベースの中のすべての通常のテーブル、パーティションテーブル、マテリアライズドビュー(外部テーブルは除く)が解析されます。 指定したテーブルがパーティションテーブルの場合、パーティションテーブル全体としての継承の統計と、個々のパーティションの統計の両方が更新されます。
column_name解析の対象とする列名です。 デフォルトは全ての列です。
VERBOSEが指定された場合、ANALYZEは進捗メッセージとして処理中のテーブルを表示します。
さらに、テーブルについての各種統計情報も表示されます。
テーブルを解析するためには、通常そのテーブルの所有者であるかスーパーユーザでなければなりません。
しかしながら、データベースの所有者は、共有カタログを除いて、そのデータベースのテーブルをすべて解析できます。
(共有カタログの制限は、データベース全体のANALYZEはスーパーユーザだけが実施できるということを意味します。)
ANALYZEは呼び出したユーザが解析する権限のないテーブルをスキップします。
外部テーブルは明示的に選択された場合にのみ解析されます。
すべての外部データラッパーがANALYZEをサポートしているとは限りません。
テーブルのラッパーがANALYZEをサポートしない場合、コマンドは警告を出力し、何も行いません。
デフォルトのPostgreSQLの設定では、自動バキュームデーモン(25.1.6参照)が、データが最初にロードされた時や通常の操作を通して変更された時にテーブルの自動解析まで面倒をみます。
もし自動バキュームが無効にしているならばANALYZEは定期的に、もしくは、テーブルの内容に大きな変更がある度に行うことを推奨します。
統計情報が正確であれば、プランナが最も適切な問い合わせ計画を選択できるようになります。
これによって、問い合わせ処理の速度が向上します。
読み取りの多いデータベースでは、VACUUMとANALYZEは、1日1回、データベースがあまり使用されていない時間帯に実行することが一般的です。
(非常に更新が激しい場合、これでは十分ではありません。)
ANALYZEは、対象とするテーブルの読み取りロックのみを必要とします。
したがって、そのテーブルに対する他の操作と並行して実行することができます。
通常、ANALYZEによって収集される統計情報には、各列の典型的な値と各列のデータ分布の概要を示すヒストグラムが含まれます。
ANALYZEによってあまり意味がないとみなされた場合(例えば、一意性制約が付加された列では、典型的な値というものは存在しません)や、列のデータ型が適切な演算子をサポートしていない場合は、片方もしくは両方の情報を省略することがあります。
第25章に、統計情報についての詳細が記載されています。
巨大なテーブルでは、ANALYZEは、全ての行を検査するのではなく、テーブルの中からランダムにサンプルを取り出して使用します。
これによって、非常に巨大なテーブルであっても短時間で解析することが可能です。
しかし、このようにして得られた統計情報はおおよそのものでしかなく、テーブルの内容に変更がなくてもANALYZEを実行する度に変化することに注意してください。
これにより、EXPLAINが表示する、プランナの推定コストも多少変化する可能性があります。
稀に、このような不確定要素のせいで、プランナがANALYZEを実行した後に異なる問い合わせ計画を選択してしまうことがあります。
これを防止するには、以下に示すようにANALYZEで収集される統計情報の量を増やしてください。
設定パラメータ変数default_statistics_targetを調整するか、もしくはALTER TABLE ... ALTER COLUMN ... SET STATISTICSを使用して列単位の統計目標を列毎に設定することで、解析の範囲を制御することができます。
目標値として設定するのは、典型的な値のリストにおけるエントリ数の最大値とヒストグラムのビンの最大数です。
デフォルトの目標値は100です。
しかし、この値は、プランナの推定精度とANALYZEの処理時間、pg_statisticの占める容量とのトレードオフによって大きくも小さくも調整されることがあります。
目標値を0に設定すると、その列に関する統計情報の収集は無効になります。
決してWHERE句、GROUP BY句、ORDER BY句に使用されない列に対しては、このような設定が有用です。
プランナにとってそのような列の統計情報は不要だからです。
解析対象列の統計情報目標値の最大値によって、統計情報を作成するためにテーブルから抽出する行数が決定します。
目標値を大きくすると、比例して、ANALYZEに要する時間とディスク容量が増加します。
ANALYZEで推定される値の1つに各列に出現する個別値の個数があります。
行の部分集合のみしか検査されませんので、統計情報の対象をできる限り大きくしたとしても、この推定値はかなり不正確になることが時々あり得ます。
この不正確性のために悪い問い合わせ計画となる場合、より正確な値を手作業で求めて、ALTER TABLE ... ALTER COLUMN ... SET (n_distinct = ...)で設定することができます。
解析中のテーブルが継承の子テーブルを持つ場合、ANALYZEは統計情報を2組収集します。1組目は親テーブルのみの行に関するもので、2組目は親テーブルとその子テーブルすべての両方の行を含むものです。
継承ツリーを全体として処理する問い合わせの計画作成では、この2組目の統計情報が必要です。
この場合、子テーブル自体は個別には解析されません。
しかし自動バキュームデーモンでは、そのテーブルに対して自動的に解析を行うかどうかを決定する際に親テーブル上の挿入や更新のみを考慮します。
このテーブルへの挿入や更新がほとんどなければ、継承関係に対する統計情報は手作業でANALYZEを実行しない限り最新状態にはなりません。
パーティション化テーブルでは、ANALYZEはすべてのパーティションから行を抽出して統計情報を集めます。それに加えて、再帰的に各パーティションに行って、統計情報を更新します。
複数レベルのパーティショニングが行なわれていたとしても、末端の各パーティションは1度だけ解析されます。
パーティショニングにより空であることが保証されていますので、(パーティションからのデータのない)親テーブルのみの統計情報は収集されません。
自動バキュームデーモンはパーティション化テーブルを処理しませんし、子だけが変更された場合に継承の親を処理することもありません。
テーブル階層の統計情報を最新に保つためには、周期的に手動でANALYZEを実行することが通常は必要です。
子テーブルやパーティションが、外部データラッパーがANALYZEをサポートしない外部テーブルであった場合には、そのテーブルは継承統計情報を集めるときに無視されます。
解析しようとするテーブルが完全に空である場合、ANALYZEはそのテーブルに対する新しい解析情報を記録しません。
これまでの統計情報はすべて保持されます。
ANALYZEを実行している各バックエンドはその進捗をpg_stat_progress_analyzeビューで報告します。
詳細は28.4.1を参照してください。
標準SQLにはANALYZE文はありません。