ApsaraDB for SelectDB では、統計の収集を手動でトリガーしたり、統計の自動収集を有効にしたりできます。収集された統計に基づいてクエリのパフォーマンスを最適化できます。
概要
ApsaraDB for SelectDB は、統計の手動収集と自動収集をサポートしています。収集された統計は、オプティマイザがデータ分布特性を理解するのに役立ちます。コストベースの最適化 (CBO) 中に、オプティマイザは述語の選択率を計算し、収集された統計に基づいて各実行プランのコストを推定します。このようにして、オプティマイザは最適なクエリプランを選択し、クエリ効率を大幅に向上させることができます。
収集される統計
ほとんどの場合、各列について以下の情報が収集されます。
情報 | 説明 |
row_count | 行の総数。 |
data_size | データの総量。 |
avg_size_byte | 値の平均の長さ。 |
ndv | 異なる値の数。 |
min | 最小値。 |
max | 最大値。 |
null_count | NULL値の数。 |
統計収集
ApsaraDB for SelectDB では、ANALYZE ステートメントを実行して、統計を手動で収集および更新できます。
構文
ANALYZE < TABLE | DATABASE table_name | db_name >
[ (column_name [, ...]) ]
[ [ WITH SYNC ] [ WITH SAMPLE PERCENT | ROWS ] ];
// テーブルまたはデータベースの統計情報を収集します。
パラメータの説明
パラメータ | 説明 |
table_name | 統計を収集する対象のテーブルの名前。 |
column_name | 統計を収集する対象の列の名前。列は、 |
sync | このパラメータを指定すると、統計を収集するジョブは同期モードで実行され、ジョブの完了後に実行結果が返されます。このパラメータを指定しない場合、統計を収集するジョブは非同期モードで実行され、ジョブ ID が返されます。 |
sample percent | rows | このパラメータを指定して、統計収集のための情報をサンプリングできます。サンプリング比率またはサンプリングする行数を指定できます。 |
例
サンプリング比率 10 % でテーブルの統計を収集します。
ANALYZE TABLE lineitem WITH SAMPLE PERCENT 10; // lineitem テーブルの統計を 10% のサンプルで収集します。100,000 行のデータをサンプリングしてテーブルの統計を収集します。
ANALYZE TABLE lineitem WITH SAMPLE ROWS 100000; // lineitem テーブルの統計を 100000 行のサンプルで収集します。
自動収集
デフォルトでは、自動収集機能は有効になっています。
実行ロジック
インポートトランザクションがコミットされると、ApsaraDB for SelectDB は、インポートトランザクションによって更新されたテーブルの行数を記録し、テーブルの統計の健全性を推定します。統計が収集されていないテーブルの場合、統計の健全性は 0 です。table_stats_health_threshold パラメータを指定して、統計の健全性のしきい値を設定できます。この例では、60 が使用されています。テーブルの統計の健全性が 60 未満の場合、ApsaraDB for SelectDB は、テーブルの統計が古くなっているとみなし、後続の操作でテーブルの統計収集ジョブをトリガーします。統計の健全性が 60 を超えるテーブルの場合、繰り返しの収集は実行されません。
パラメータ設定
統計収集ジョブは、一定量のシステムリソースを消費します。オーバーヘッドを最小限に抑えるために、ApsaraDB for SelectDB は、サイズが指定されたしきい値を超えるテーブルの統計を収集する際に、自動的にサンプリングを使用します。デフォルトでは、しきい値は 5 GiB に設定されています。enormous_table_lower_bound_size_in_bytes フロントエンド (FE) パラメータを指定して、しきい値を調整できます。デフォルトでは、ApsaraDB for SelectDB は自動収集中に 4,194,304 (2^22) 行のデータをサンプリングして、システムの負荷を軽減し、統計収集ジョブをできるだけ早く完了します。
より多くの行をサンプリングして、より正確なデータ分布情報を取得する場合、enormous_table_default_sample_rows パラメータを指定して、サンプリングする行数を増やすことができます。さらに、ApsaraDB for SelectDB は、enormous_table_lower_bound_size_in_bytes パラメータに指定されたしきい値を超えるサイズのテーブルの収集間隔が特定の期間以上になるようにします。デフォルトでは、最小間隔は 12 時間です。enormous_table_auto_analyze_interval_in_millis パラメータを指定して、最小間隔を調整できます。
自動収集ジョブの実行によるビジネスへの影響を防ぐために、ビジネス要件に基づいて auto_analyze_start_time パラメータと auto_analyze_end_time パラメータを指定し、自動収集ジョブがオフピーク時に実行されるように指定できます。また、enable_auto_analyze パラメータを false に設定して、自動収集機能を無効にすることもできます。
デフォルトでは、外部カタログの自動収集機能は無効になっています。外部カタログの自動収集機能が有効になっていると、外部カタログには大量の履歴データが含まれているため、過剰なリソースが消費される可能性があります。外部カタログのプロパティを設定して、外部カタログの自動収集機能を有効または無効にすることができます。
ALTER CATALOG external_catalog SET PROPERTIES ('enable.auto.analyze'='true'); // 外部カタログの自動収集機能を有効にします。
ALTER CATALOG external_catalog SET PROPERTIES ('enable.auto.analyze'='false'); // 外部カタログの自動収集機能を無効にします。
ジョブ管理
統計収集ジョブの表示
SHOW ANALYZE ステートメントを実行して、統計収集ジョブに関する情報を表示できます。
構文
SHOW [AUTO] ANALYZE < table_name | job_id >
[ WHERE [ STATE = [ "PENDING" | "RUNNING" | "FINISHED" | "FAILED" ] ] ];
// 統計収集ジョブの情報を表示します。
パラメータの説明
パラメータ | 説明 |
AUTO | 履歴自動収集ジョブに関する情報。 説明 デフォルトでは、完了した最新の自動収集ジョブのうち 20,000 件のみの状態が保持されます。 |
table_name | 統計収集ジョブを表示する対象のテーブルの名前。 |
job_id | 表示する統計収集ジョブの ID。ジョブ ID は、非同期モードで統計を収集するために実行された |
例
SHOW ANALYZE 245073\G;
// ID が 245073 の統計収集ジョブの情報を表示します。
*************************** 1. row ***************************
job_id: 245073
catalog_name: internal
db_name: default_cluster:tpch
tbl_name: lineitem
col_name: [l_returnflag,l_receiptdate,l_tax,l_shipmode,l_suppkey,l_shipdate,l_commitdate,l_partkey,l_orderkey,l_quantity,l_linestatus,l_comment,l_extendedprice,l_linenumber,l_discount,l_shipinstruct]
job_type: MANUAL
analysis_type: FUNDAMENTALS
message:
last_exec_time_in_ms: 2023-11-07 11:00:52
state: FINISHED
progress: 16 Finished | 0 Failed | 0 In Progress | 16 Total
schedule_type: ONCE
次の表に、出力のパラメータを示します。
パラメータ | 説明 |
job_id | 統計収集ジョブの ID。 |
catalog_name | カタログ名。 |
db_name | データベース名。 |
tbl_name | テーブル名。 |
col_name | 列名。 |
job_type | ジョブのタイプ。 |
analysis_type | 統計のタイプ。 |
message | 統計収集ジョブに関する情報。 |
last_exec_time_in_ms | 統計収集ジョブが最後に実行された時刻。 |
state | 統計収集ジョブの状態。 |
schedule_type | 統計収集ジョブのスケジューリング方法。 |
テーブルの統計収集に関する情報の表示
SHOW TABLE STATS ステートメントを実行して、テーブルの統計収集に関する情報を表示できます。
構文
SHOW TABLE STATS <table_name>;
// 指定されたテーブルの統計情報を表示します。
パラメータの説明
パラメータ | 説明 |
table_name | 統計情報を表示する対象のテーブルの名前。 |
例
次のステートメントは、lineitem テーブルの収集された統計に関する情報を表示する例を示しています。
SHOW TABLE STATS lineitem\G
// lineitem テーブルの統計情報を表示します。
*************************** 1. row ***************************
updated_rows: 0
query_times: 0
row_count: 6001215
updated_time: 2023-11-07
columns: [l_returnflag, l_receiptdate, l_tax, l_shipmode, l_suppkey, l_shipdate, l_commitdate, l_partkey, l_orderkey, l_quantity, l_linestatus, l_comment, l_extendedprice, l_linenumber, l_discount, l_shipinstruct]
trigger: MANUAL
次の表に、出力のパラメータを示します。
パラメータ | 説明 |
updated_rows | 最後の ANALYZE ステートメントによって更新されたテーブルの行数。 |
query_times | 予約済みの列。今後のバージョンでは、このパラメータはテーブルで実行されたクエリの数を示します。 |
row_count | テーブルの行数。このパラメータの値は、実行中の正確な行数を示すものではありません。 |
updated_time | 収集された統計が最後に更新された時刻。 |
columns | 統計が収集された列。 |
trigger | 統計収集ジョブのトリガー方法。 |
列の統計収集に関する情報の表示
各統計収集ジョブは 1 つ以上のタスクで構成され、各タスクは列の収集に対応します。次のステートメントを実行して、特定の列の統計収集に関する情報を表示できます。
構文
SHOW ANALYZE TASK STATUS [job_id]
// 特定のジョブ ID に関連付けられた統計収集タスクのステータスを表示します。
パラメータの説明
パラメータ | 説明 |
job_id | 統計収集ジョブの ID。 |
例
次のステートメントは、ID が 20038 の統計収集タスクに関する情報を表示する例を示しています。
SHOW ANALYZE TASK STATUS 20038;
// ジョブ ID 20038 のタスクステータスを表示します。
+---------+----------+---------+----------------------+----------+
| task_id | col_name | message | last_exec_time_in_ms | state |
+---------+----------+---------+----------------------+----------+
| 20039 | col4 | | 2023-06-01 17:22:15 | FINISHED |
| 20040 | col2 | | 2023-06-01 17:22:15 | FINISHED |
| 20041 | col3 | | 2023-06-01 17:22:15 | FINISHED |
| 20042 | col1 | | 2023-06-01 17:22:15 | FINISHED |
+---------+----------+---------+----------------------+----------+列の統計の表示
SHOW COLUMN STATS ステートメントを実行して、列の統計を表示できます。
構文
SHOW COLUMN [cached] STATS table_name [ (column_name [, ...]) ];
// 指定されたテーブルの列の統計情報を表示します。
パラメータの説明
パラメータ | 説明 |
cached | FE メモリキャッシュ内の統計。 |
table_name | 列統計を表示する対象のテーブルの名前。 |
column_name | 統計を表示する対象の列の名前。列は、 |
例
次のステートメントは、l_tax 列の統計を表示する例を示しています。
SHOW COLUMN STATS lineitem(l_tax)\G
// lineitem テーブルの l_tax 列の統計情報を表示します。
*************************** 1. row ***************************
column_name: l_tax
count: 6001215.0
ndv: 9.0
num_null: 0.0
data_size: 4.800972E7
avg_size_byte: 8.0
min: 0.00
max: 0.08
method: FULL
type: FUNDAMENTALS
trigger: MANUAL
query_times: 0
updated_time: 2023-11-07 11:00:46
統計収集ジョブの停止
KILL ANALYZE ステートメントを実行して、統計収集ジョブを停止できます。
構文
KILL ANALYZE job_id;
// 指定されたジョブ ID の統計収集ジョブを停止します。
パラメータの説明
パラメータ | 説明 |
job_id | 統計収集ジョブの ID。ジョブ ID は、非同期モードで統計を収集するために実行された |
例
次のステートメントは、ID が 52357 の統計収集ジョブを停止する例を示しています。
KILL ANALYZE 52357;
// ID が 52357 の統計収集ジョブを停止します。
セッション変数と FE 設定項目
セッション変数
セッション変数 | デフォルト値 | 説明 |
auto_analyze_start_time | 00:00:00 | 自動収集ジョブの開始時刻。 |
auto_analyze_end_time | 23:59:59 | 自動収集ジョブの終了時刻。 |
enable_auto_analyze | true | 自動収集機能を有効にするかどうかを指定します。 |
enormous_table_default_sample_rows | 4194304 | 大きなテーブルでサンプリングする行数。 |
enormous_table_lower_bound_size_in_bytes | 5368709120 | サンプリング収集のしきい値。テーブルのサイズがこの値を超えると、自動収集中にサンプリング収集が自動的に使用されます。 |
enormous_table_auto_analyze_interval_in_millis | 43200000 | 大きなテーブルに対して自動収集を実行する最小間隔。指定された間隔中に、 |
table_stats_health_threshold | 60 | 統計の健全性のしきい値。有効な値: 0 ~ 100。更新されたデータの比率が |
analyze_timeout | 43200 | 統計収集ジョブのタイムアウト期間。単位: 秒。 |
auto_analyze_table_width_threshold | 70 | 自動収集に使用するテーブルに含めることができる列の最大数。テーブルの列数がこの値を超えると、テーブルは自動収集に参加しません。 |
FE 設定項目
次の FE 設定項目は、収集される統計に関連しています。ほとんどの場合、これらの設定項目に注目する必要はありません。
FE 設定項目 | デフォルト値 | 説明 |
analyze_record_limit | 20000 | 統計収集ジョブの実行を記録するために保存できる永続行の最大数。 |
stats_cache_size | 500000 | FE 側でキャッシュできる統計行の最大数。 |
statistics_simultaneously_running_task_num | 3 | 同時に実行できる非同期統計収集ジョブの最大数。 |
statistics_sql_mem_limit_in_bytes | 2,147,483,648 バイト (2 GiB) | 統計収集のために各 SQL ステートメントが占有できる最大バックエンド (BE) メモリ。 |
FAQ
Q: ANALYZE ステートメントを送信した後に「Stats table not available...」エラーが報告された場合はどうすればよいですか?
A: BE の状態を確認してください。
SHOW BACKENDSステートメントを実行して、BE の状態が正常かどうかを確認できます。BE の状態が正常な場合は、ADMIN SHOW REPLICA STATUS FROM __internal_schema.[tbl_in_this_db]ステートメントを実行して、データベース内のタブレットの状態を確認できます。すべてのタブレットの状態が正常であることを確認してください。ANALYZE ステートメントの実行中に、収集された統計は__internal_schema.column_statisticsという名前の内部テーブルに書き込まれます。ANALYZE ステートメントの実行前に、FE はテーブルのタブレットの状態を確認します。使用できないタブレットが存在する場合、統計収集の要求は拒否されます。Q: 大きなテーブルから統計を収集できない場合はどうすればよいですか?
A:
ANALYZE ... WITH SAMPLE...ステートメントを実行して、大きなテーブルから統計を収集することをお勧めします。ANALYZE ステートメントが消費できるリソースは厳しく制限されています。この場合、大きなテーブルで ANALYZE ステートメントを実行すると、実行がタイムアウトしたり、使用可能な BE メモリによって制限されたりする可能性があります。