クエリプロファイルを分析して、クエリのパフォーマンスを向上させることができます。 このトピックでは、ApsaraDB for SelectDB のクエリプロファイルを取得する方法について説明します。ApsaraDB for SelectDB
クエリプロファイル機能を有効にする
enable_profile 変数を設定して、クエリプロファイル機能を有効にします。詳細については、「変数管理」をご参照ください。
SET enable_profile=true;クエリプロファイル機能を有効にすると、SelectDB は各クエリの実行に対してプロファイルを生成します。
クエリプロファイルには、各ノードでのクエリの実行の詳細が含まれています。これは、クエリのパフォーマンスボトルネックを分析するのに役立ちます。
クエリプロファイルを表示する
次の文を実行して、保存されているすべてのクエリプロファイルを表示します。
次のステートメントは、カーネルバージョンが SelectDB Core V4.0.0 より前の SelectDB インスタンスでのみサポートされています。インスタンスで SelectDB Core V4.0.0 以降を実行している場合は、SelectDB コンソールでクエリプロファイルをプレビューまたはダウンロードすることをお勧めします。 HTTP リクエストを送信してクエリプロファイルを取得することもできます。詳細については、「クエリアudit機能を使用する」および「クエリプロファイルをエクスポートする」をご参照ください。
SHOW QUERY PROFILE "/"\G;返された結果セットでは、データの各行がクエリプロファイルに対応しています。プロファイル ID に基づいて、クエリプロファイルの詳細を表示できます。
クエリプロファイルに送信される HTTP リクエストでは、Query ID や query_id などのフィールドは profile ID を示します。
SHOW QUERY PROFILE "/"\G
*************************** 1. row ***************************
Profile ID: c257c52f93e149ee-ace8ac14e8c9fef9
Task Type: QUERY
Start Time: 2021-04-08 11:30:50
End Time: 2021-04-08 11:30:50
Total: 9ms
Task State: EOF
User: root
Default Db: default_cluster:db1
Sql Statement: select tbl1.k1, sum(tbl1.k2) from tbl1 join tbl2 on tbl1.k1 = tbl2.k1 group by tbl1.k1 order by tbl1.k1クエリプロファイルを使用する
次の手順を実行して、SQL クエリ文のパフォーマンスボトルネックをトラブルシューティングします。
実行プランツリーを表示します。
この手順は、主に実行プラン全体を分析し、各フラグメントの実行時間を表示するために使用されます。返された結果では、各ノードはそれが属するフラグメントでマークされ、各フラグメントの送信者ノードはこのフラグメントの実行時間でマークされます。時間は、フラグメント内のすべての実行ユニットの実行時間の中で最も長いものです。この実行プランツリーは、最も時間のかかるフラグメントを見つけるのに役立ちます。次のサンプルコードは、実行プランツリーの例を示しています。
SHOW QUERY PROFILE "/c257c52f93e149ee-ace8ac14e8c9fef9"\G *************************** 1. row *************************** Fragments: ┌──────────────────────┐ │[-1: DataBufferSender]│ │Fragment: 0 │ │MaxActiveTime: 6.626 ms│ └──────────────────────┘ │ ┌──────────────────┐ │[9: EXCHANGE_NODE]│ │Fragment: 0 │ └──────────────────┘ │ ┌──────────────────────┐ │[9: DataStreamSender] │ │Fragment: 1 │ │MaxActiveTime: 5.449 ms│ └──────────────────────┘ │ ┌──────────────┐ │[4: SORT_NODE]│ │Fragment: 1 │ └──────────────┘ ┌┘ ┌─────────────────────┐ │[8: AGGREGATION_NODE]│ │Fragment: 1 │ └─────────────────────┘ └┐ ┌──────────────────┐ │[7: EXCHANGE_NODE]│ │Fragment: 1 │ └──────────────────┘ │ ┌──────────────────────┐ │[7: DataStreamSender] │ │Fragment: 2 │ │MaxActiveTime: 3.505 ms│ └──────────────────────┘ ┌┘ ┌─────────────────────┐ │[3: AGGREGATION_NODE]│ │Fragment: 2 │ └─────────────────────┘ │ ┌───────────────────┐ │[2: HASH_JOIN_NODE]│ │Fragment: 2 │ └───────────────────┘ ┌────────────┴────────────┐ ┌──────────────────┐ ┌──────────────────┐ │[5: EXCHANGE_NODE]│ │[6: EXCHANGE_NODE]│ │Fragment: 2 │ │Fragment: 2 │ └──────────────────┘ └──────────────────┘ │ │ ┌─────────────────────┐ ┌────────────────────────┐ │[5: DataStreamSender]│ │[6: DataStreamSender] │ │Fragment: 4 │ │Fragment: 3 │ │MaxActiveTime: 1.87 ms│ │MaxActiveTime: 636.767 us│ └─────────────────────┘ └────────────────────────┘ │ ┌┘ ┌───────────────────┐ ┌───────────────────┐ │[0: OLAP_SCAN_NODE]│ │[1: OLAP_SCAN_NODE]│ │Fragment: 4 │ │Fragment: 3 │ └──────────────────┘ └──────────────────┘ │ │ ┌─────────────┐ ┌─────────────┐ │[OlapScanner]│ │[OlapScanner]│ │Fragment: 4 │ │Fragment: 3 │ └─────────────┘ └─────────────┘ │ │ ┌─────────────────┐ ┌─────────────────┐ │[SegmentIterator]│ │[SegmentIterator]│ │Fragment: 4 │ │Fragment: 3 │ └─────────────────┘ └─────────────────┘ 1 row in set (0.02 sec)特定のフラグメントの実行ユニットを表示します。
前の例では、フラグメント 1 が最も時間のかかるフラグメントです。したがって、フラグメント 1 の実行ユニットを表示できます。次のサンプルコードは、フラグメント 1 のすべての実行ユニットの実行ノードと実行時間をクエリする方法を示しています。
SHOW QUERY PROFILE "/c257c52f93e149ee-ace8ac14e8c9fef9/1"; +-----------------------------------+-------------------+------------+ | Instances | Host | ActiveTime | +-----------------------------------+-------------------+------------+ | c257c52f93e149ee-ace8ac14e8c9ff03 | 10.200.00.01:9060 | 5.449ms | | c257c52f93e149ee-ace8ac14e8c9ff05 | 10.200.00.02:9060 | 5.367ms | | c257c52f93e149ee-ace8ac14e8c9ff04 | 10.200.00.03:9060 | 5.358ms | +-----------------------------------+-------------------+------------+特定の実行ユニットを表示します。
特定の実行ユニットの各オペレーターのプロファイルを表示できます。次のサンプルコードは、フラグメント 1 の実行ユニット c257c52f93e149ee-ace8ac14e8c9ff03 の各オペレーターのプロファイルをクエリする方法を示しています。
SHOW QUERY PROFILE "/c257c52f93e149ee-ace8ac14e8c9fef9/1/c257c52f93e149ee-ace8ac14e8c9ff03"\G *************************** 1. row *************************** Instance: ┌───────────────────────────────────────┐ │[9: DataStreamSender] │ │(Active: 37.222 us, non-child: 0.40) │ │ - Counters: │ │ - BytesSent: 0.00 │ │ - IgnoreRows: 0 │ │ - OverallThroughput: 0.0 /sec │ │ - PeakMemoryUsage: 8.00 KB │ │ - SerializeBatchTime: 0ns │ │ - UncompressedRowBatchSize: 0.00 │ └───────────────────────────────────────┘ └┐ │ ┌──────────────────────────────────┐ │[4: SORT_NODE] │ │(Active: 5.421 ms, non-child: 0.71)│ │ - Counters: │ │ - PeakMemoryUsage: 12.00 KB │ │ - RowsReturned: 0 │ │ - RowsReturnedRate: 0 │ └──────────────────────────────────┘ ┌┘ │ ┌───────────────────────────────────┐ │[8: AGGREGATION_NODE] │ │(Active: 5.355 ms, non-child: 10.68)│ │ - Counters: │ │ - BuildTime: 3.701us │ │ - GetResultsTime: 0 ns │ │ - HTResize: 0 │ │ - HTResizeTime: 1.211 us │ │ - HashBuckets: 0 │ │ - HashCollisions: 0 │ │ - HashFailedProbe: 0 │ │ - HashFilledBuckets: 0 │ │ - HashProbe: 0 │ │ - HashTravelLength: 0 │ │ - LargestPartitionPercent: 0 │ │ - MaxPartitionLevel: 0 │ │ - NumRepartitions: 0 │ │ - PartitionsCreated: 16 │ │ - PeakMemoryUsage: 34.02 MB │ │ - RowsProcessed: 0 │ │ - RowsRepartitioned: 0 │ │ - RowsReturned: 0 │ │ - RowsReturnedRate: 0 │ │ - SpilledPartitions: 0 │ └───────────────────────────────────┘ └┐ │ ┌──────────────────────────────────────────┐ │[7: EXCHANGE_NODE] │ │(Active: 4.360 ms, non-child: 46.84) │ │ - Counters: │ │ - BytesReceived: 0.00 │ │ - ConvertRowBatchTime: 387 ns │ │ - DataArrivalWaitTime: 4.357 ms │ │ - DeserializeRowBatchTimer: 0 ns │ │ - FirstBatchArrivalWaitTime: 4.356 ms│ │ - PeakMemoryUsage: 0.00 │ │ - RowsReturned: 0 │ │ - RowsReturnedRate: 0 │ │ - SendersBlockedTotalTimer(*): 0 ns │ └──────────────────────────────────────────┘
クエリプロファイルをエクスポートする
後続の分析のためにクエリプロファイルをエクスポートするには、次の手順を実行します。
SelectDB Core V3.0.4 以降を実行している SelectDB インスタンスのみがこの機能をサポートしています。
クエリプロファイル機能を有効にします。
SET enable_profile=true;クエリ文を実行します。
次のコードは、クエリ文の例を示しています。実際の使用で使用する SQL クエリ文に置き換えてください。
-- SQL リクエストを送信します。この場合、クエリ文のプロファイルが生成されます。 SELECT count(1) FROM test_table LIMIT 10;プロファイル ID をクエリします。
SelectDB Core V3.0.x
次のサンプルコードは、SelectDB Core V3.0.x を実行している SelectDB インスタンスのプロファイル ID をクエリする方法の例を示しています。
SHOW QUERY PROFILE "/"; +-----------------------------------+-----------+---------------------+---------------------+-------+------------+-------+------------------------------------+-------------------------------+ | Profile ID | Task Type | Start Time | End Time | Total | Task State | User | Default Db | Sql Statement | +-----------------------------------+-----------+---------------------+---------------------+-------+------------+-------+------------------------------------+-------------------------------+ | b9c9ba063d9d4365-97878361371e757a | QUERY | 2024-02-07 17:40:04 | 2024-02-07 17:40:04 | 32ms | EOF | admin | default_cluster:information_schema | select * from user_privileges | | 8800c306137e4072-9bb1ed419f4ac9f2 | QUERY | 2024-02-07 17:40:00 | 2024-02-07 17:40:00 | 3ms | ERR | admin | default_cluster:information_schema | select * from user_priveleges | | e2efdd1a996c4de2-ab939ad49b409990 | QUERY | 2024-02-07 17:39:51 | 2024-02-07 17:39:51 | 13ms | EOF | admin | | SELECT DATABASE() | +-----------------------------------+-----------+---------------------+---------------------+-------+------------+-------+------------------------------------+-------------------------------+SelectDB Core V4.0.x
次のサンプルコードは、SelectDB Core V4.0.x を実行している ApsaraDB for SelectDB インスタンスのプロファイル ID をクエリする方法の例を示しています。
Query IDフィールドはprofile IDを示します。curl -u'<userName>:<userPassword>' "http://<selectdbAddress>:<httpPort>/rest/v2/manager/query/query_info?is_all_node=true" # レスポンス { "msg": "success", "code": 0, "data": { "column_names": [ "Query ID", "FE Node", "Query User", "Execution Database", "Sql", "Query Type", "Start Time", "End Time", "Execution Duration", "Status" ], "rows": [ [ ... ] ] }, "count": 0 }プロファイル ID に基づいて、curl コマンドを実行してプロファイルをファイルにエクスポートします。
curl -u'<userName>:<userPassword>' "http://<selectdbAddress>:<httpPort>/api/profile?query_id=<query_id>" # リダイレクト記号を使用して、プロファイルをファイルにエクスポートできます。 curl -u'<userName>:<userPassword>' "http://<selectdbAddress>:<httpPort>/api/profile?query_id=<query_id>" > res.txtパラメーター
パラメーター
説明
userName
SelectDB インスタンスにアクセスするために使用されるユーザー名。
userPassword
SelectDB インスタンスにアクセスするために使用されるパスワード。
selectdbAddress
SelectDB インスタンスのエンドポイント。
httpPort
SelectDB インスタンスの HTTP ポート番号。デフォルト値: 8080。
query_id
プロファイルのクエリ ID。
プロファイルパラメーター
次の表は、収集された統計情報のパラメーターについて説明しています。
フラグメント
パラメーター | 説明 |
AverageThreadTokens | スレッドプールの使用を除く、フラグメントの実行に使用されるスレッドの数。 |
Buffer Pool PeakReservation | バッファープールのピークメモリ使用量。 |
MemoryLimit | クエリのメモリ制限。 |
PeakMemoryUsage | クエリ中の実行ユニットのピークメモリ使用量。 |
RowsProduced | カラムが処理される行の数。 |
BlockMgr
パラメーター | 説明 |
BlocksCreated | BlockManager によって作成されるブロックの数。 |
BlocksRecycled | 再利用されるブロックの数。 |
BytesWritten | ディスクに書き込まれるデータの合計サイズ。 |
MaxBlockSize | 単一ブロックのサイズ。 |
TotalReadBlockTime | ブロックの読み取りに消費される合計時間。 |
DataStreamSender
パラメーター | 説明 |
BytesSent | 送信されたデータの合計サイズ。データサイズは、次の式を使用して計算されます。送信されたデータの合計サイズ = 受信者の数 × 送信されたデータのサイズ。 |
IgnoreRows | フィルターされた行の数。 |
LocalBytesSent | データ交換中にローカルノードによって送信され、ローカルノードによって受信されたデータのサイズ。 |
OverallThroughput | 合計スループット。合計スループットは、次の式を使用して計算されます。合計スループット = BytesSent パラメーターの値 / 実行時間。 |
SerializeBatchTime | 送信されるデータのシリアル化に費やされた時間。 |
UncompressedRowBatchSize | 圧縮前の送信済み RowBatch データのサイズ。 |
ODBC_TABLE_SINK
パラメータ | 説明 |
NumSentRows | 外部テーブルに書き込まれた行の総数。 |
TupleConvertTime | 送信されたデータを INSERT 文にシリアル化するのにかかった時間。 |
ResultSendTime | Open Database Connectivity (ODBC) ドライバーを使用してデータを書き込むのにかかった時間。 |
EXCHANGE_NODE
パラメーター | 説明 |
BytesReceived | ネットワーク経由で受信されるデータのサイズ。 |
MergeGetNext | 子ノードでソートが実行される場合、交換ノードは統合マージとソートを実行し、順序付けられた結果を出力します。このパラメーターは、MergeGetNextBatch パラメーターで指定された時間を含む、マージとソートに消費された合計時間を示します。 |
MergeGetNextBatch | マージノードがデータを取得するために消費する時間。単一レベルのマージとソートの場合、データを取得するオブジェクトはネットワークキューです。複数レベルのマージとソートの場合、データを取得するオブジェクトは子マージャーです。 |
ChildMergeGetNext | 送信側が多すぎる場合、単一スレッドのマージはパフォーマンスのボトルネックになります。この場合、ApsaraDB for SelectDB は子マージノードで複数のスレッドを起動し、並列でマージとソートを実行します。このパラメーターは、子マージノードがソートに消費した時間を記録します。これは、すべてのスレッドが消費した時間の合計です。 |
ChildMergeGetNextBatch | 子マージノードがデータを取得するために消費する時間。過剰な時間が消費された場合、子データ送信ノードにボトルネックが発生している可能性があります。 |
DataArrivalWaitTime | 送信側がデータを送信するのを待つ合計時間。 |
FirstBatchArrivalWaitTime | 最初のバッチが送信側からデータを取得するのを待つ時間。 |
DeserializeRowBatchTimer | ネットワークデータを逆シリアル化するために消費される時間。 |
SendersBlockedTotalTimer(*) | DataStreamRecv キューのメモリがいっぱいになった場合の、送信側の合計待機時間。 |
ConvertRowBatchTime | 受信データを RowBatch データに変換するために消費される時間。 |
RowsReturned | 受信される行数。 |
RowsReturnedRate | 行が受信される速度。 |
SORT_NODE
パラメータ | 説明 |
InMemorySortTime | メモリ内ソートに費やされた時間。 |
InitialRunsCreated | ソートを初期化する回数。メモリ内ソートの場合は 1 です。 |
SortDataSize | ソートされるデータの合計サイズ。 |
MergeGetNext | MergeSort が複数のソート済み実行から次のバッチを取得するのに費やされた時間。データがディスクに書き込まれる場合にのみタイミングが実行されます。 |
MergeGetNextBatch | MergeSort が次のソート済み実行のバッチを抽出するのに費やされた時間。データがディスクに書き込まれる場合にのみタイミングが実行されます。 |
TotalMergesPerformed | 外部マージが実行された回数。 |
AGGREGATION_NODE
パラメータ | 説明 |
PartitionsCreated | 集計クエリが分割されるパーティションの数。 |
GetResultsTime | パーティションから集計結果を取得するために消費された時間。 |
HTResizeTime | ハッシュテーブルのサイズ変更に消費された時間。 |
HTResize | ハッシュテーブルのサイズが変更された回数。 |
HashBuckets | ハッシュテーブルのバケット数。 |
HashBucketsWithDuplicate | ハッシュテーブル内で重複ノードを持つバケットの数。 |
HashCollisions | ハッシュテーブルで発生したハッシュ衝突の数。 |
HashDuplicateNodes | ハッシュテーブル内の同じバケットに属する重複ノードの数。 |
HashFailedProbe | ハッシュテーブルで実行されたプローブ操作が失敗した回数。 |
HashFilledBuckets | ハッシュテーブル内でデータが格納されているバケットの数。 |
HashProbe | ハッシュテーブルがクエリされた回数。 |
HashTravelLength | ハッシュテーブルのクエリ中に移動したステップ数。 |
HASH_JOIN_NODE
パラメータ | 説明 |
ExecOption | 右側の子ノードのハッシュテーブル構築方法。メソッドには、同期メソッドと非同期メソッドが含まれます。結合の右側の子ノードは、テーブルまたはサブクエリの場合があります。このルールは左側の子ノードにも適用されます。 |
BuildBuckets | ハッシュテーブルのバケット数。 |
BuildRows | ハッシュテーブルの行数。 |
BuildTime | ハッシュテーブルの構築に費やされた時間。 |
LoadFactor | ハッシュテーブルの負荷率。空でないバケットの数を示します。 |
ProbeRows | 左側の子ノードが走査された後にハッシュプローブ操作が実行される行数。 |
ProbeTime | 左側の子ノード側で RowBatch の GetNext 操作を呼び出すのに費やされた時間を除き、ハッシュプローブ操作のために左側の子ノードを走査するのに費やされた時間。 |
PushDownComputeTime | 述語プッシュダウン条件の計算に費やされた時間。 |
PushDownTime | 述語プッシュダウンに費やされた合計時間。条件を満たす右側の子ノードに対する結合クエリは、左側の子ノードに対する IN クエリに変換されます。 |
CROSS_JOIN_NODE
パラメータ | 説明 |
ExecOption | 右の子ノードの RowBatchList の構築方法。同期メソッドと非同期メソッドがあります。 |
BuildRows | RowBatchList の行数。右の子ノードの行数を示します。 |
BuildTime | RowBatchList の構築に要した時間。 |
LeftChildRows | 左の子ノードの行数。 |
LeftChildTime | デカルト積を生成するために左の子ノードと右の子ノードを走査するのに要した時間。左の子ノード側で RowBatch の GetNext 操作を呼び出すのに要した時間は含まれません。 |
UNION_NODE
パラメーター | 説明 |
MaterializeExprsEvaluateTime | UNION の両側のフィールド タイプに不整合がある場合に、タイプ変換式を計算し、結果を具体化するのにかかった時間です。 |
ANALYTIC_EVAL_NODE
パラメーター | 説明 |
EvaluationTime | 分析関数(ウィンドウ関数)の計算に消費された合計時間。 |
GetNewBlockTime | 初期化中に新しいブロックの適用に消費された時間。ブロックは、分析関数の計算のために Rows ウィンドウまたはパーティション全体をキャッシュするために使用されます。 |
PinTime | 新しいブロックの適用、またはディスクに書き込まれたブロックをメモリに再読み込みするのに消費された時間。 |
UnpinTime | ブロックが不要な場合、または現在のオペレーターのメモリ負荷が高い場合に、ブロックからディスクにデータを書き込むのに消費された時間。 |
OLAP_SCAN_NODE
OLAP_SCAN_NODE は、特定のデータ スキャン タスクを担当します。1 つ以上の OLAP スキャナーを生成します。各スキャナ スレッドは、部分的なデータのスキャンを担当します。
クエリ内の述語条件の一部またはすべてが OLAP_SCAN_NODE にプッシュされます。 これらの述語条件の一部は、ストレージエンジンのインデックスを使用してデータフィルタリングを行うために、ストレージエンジンにプッシュダウンされます。 その他の述語条件は OLAP_SCAN_NODE に保持され、ストレージエンジンから返されたデータをフィルタリングするために使用されます。
OLAP_SCAN_NODE のプロファイルは、一般的にデータスキャンの効率を分析するために使用されます。プロファイルは、呼び出し関係に基づいて、次の 3 つのレイヤーに分割されます。OLAP_SCAN_NODE、OlapScanner、および SegmentIterator。
次のサンプルコードは、典型的な OLAP_SCAN_NODE ノードを示しています。一部のメトリックの意味は、ストレージフォーマット(V1 または V2)によって異なる場合があります。
OLAP_SCAN_NODE (id=0):(Active: 1.2ms, % non-child: 0.00%)
- BytesRead: 265.00 B # データファイルから読み取られたデータのサイズです。たとえば、10個の32ビット整数が読み取られた場合、データサイズは 10 × 4 バイト = 40 バイトです。このパラメーターは、メモリに完全に表示されているデータのサイズのみを示し、実際の I/O サイズは示しません。
- NumDiskAccess: 1 # ScanNode ノードに関係するディスクの数です。
- NumScanners: 20 # ScanNode ノードによって生成されたスキャナーの数です。
- PeakMemoryUsage: 0.00 # クエリ中のピークメモリ使用量です。メモリは使用されていません。
- RowsRead: 7 # ストレージエンジンからスキャナーに返された行数です。スキャナーによってフィルタリングされた行数は含まれません。
- RowsReturned: 7 # ScanNode ノードから親ノードに返された行数です。
- RowsReturnedRate: 6.979K /sec # RowsReturned/ActiveTime
-TabletCount: 20 # ScanNode ノードに関係するタブレットの数です。
- TotalReadThroughput: 74.70 KB/sec # BytesRead を、クエリの開始から完了までのこのノードでの合計実行時間で割ることによって計算される、合計読み取りスループットです。I/O 制約のあるクエリの場合、この値はディスクの合計スループットに近くなります。
- ScannerBatchWaitTime: 426.886us # 転送スレッドがスキャナー スレッドから RowBatch データが返されるのを待機する時間です。
- ScannerWorkerWaitTime: 17.745us # スキャナースレッドがスレッドプール内の使用可能なワーカースレッドを待機する時間です。
OlapScanner:
- BlockConvertTime: 8.941us # ベクトル化されたブロックを行構造の RowBlock に変換するのにかかった時間です。ベクトル化されたブロックは、V1 では VectorizedRowBatch、V2 では RowBlockV2 です。
- BlockFetchTime: 468.974us # 行セットリーダーがブロックを取得する時間です。
- ReaderInitTime: 5.475ms # OLAP スキャナーがリーダーを初期化する時間です。V1 では MergeHeap の作成時間が含まれます。V2 では、すべてのレベルのイテレーターを生成し、最初のブロックグループを読み取るのにかかった時間が含まれます。
- RowsDelFiltered: 0 # フィルターで除外された行数です。タブレット内の DELETE 情報に基づくものと、Unique Key モデルで削除のマークが付けられた行が含まれます。
- RowsPushedCondFiltered: 0 # プッシュダウンされた述語に基づいてフィルターで除外された条件です。たとえば、結合操作で BuildTable から ProbeTable に渡される条件などです。この値は正確ではありません。フィルタリング効果が低い場合は、フィルタリング操作は実行されません。
- ScanTime: 39.24us # データが ScanNode から親ノードに返されるまでの時間です。
- ShowHintsTime_V1: 0ns # このパラメーターは V2 では適用されません。V1 では、ScanRange 分割のためにいくつかのデータが読み取られます。
SegmentIterator:
- BitmapIndexFilterTimer: 779ns # ビットマップインデックスを使用してデータをフィルタリングするのにかかった時間です。
- BlockLoadTime: 415.925us # セグメントリーダー(V1)またはセグメントイテレーター(V2)がブロックを取得するのにかかった時間です。
- BlockSeekCount: 12 # セグメントの読み取り中にブロックシークが実行された回数です。
- BlockSeekTime: 222.556us # セグメントの読み取り中にブロックシークにかかった時間です。
- BlocksLoad: 6 # 読み取られたブロックの数です。
- CachedPagesNum: 30 # V2 でのみ、ページキャッシュが有効になった後にキャッシュにヒットしたページの数です。
- CompressedBytesRead: 0.00 # V1 では、ファイルから読み取られた展開前のデータのサイズ、または V2 では、ページキャッシュにヒットしなかった圧縮前の読み取りページのサイズです。
- DecompressorTimer: 0ns # データの展開にかかった時間です。
- IOTimer: 0ns # オペレーティングシステムからデータを読み取る実際の I/O 時間です。
- IndexLoadTime_V1: 0ns # V1 でのみ、インデックスストリームの読み取りにかかった時間です。
- NumSegmentFiltered: 0 # 列の統計情報とクエリ条件に基づいて完全にフィルターで除外されたセグメントの数です。
- NumSegmentTotal: 6 # クエリに関係するすべてのセグメントの数です。
- RawRowsRead: 7 # ストレージエンジンから読み取られたソースデータ行の数です。詳細については、次のセクションを参照してください。
- RowsBitmapIndexFiltered: 0 # V2 でのみ、ビットマップインデックスを使用してフィルターで除外された行数です。
- RowsBloomFilterFiltered: 0 # V2 でのみ、BloomFilter インデックスを使用してフィルターで除外された行数です。
- RowsKeyRangeFiltered: 0 # V2 でのみ、SortkeyIndex インデックスを使用してフィルターで除外された行数です。
- RowsStatsFiltered: 0 # V2 で ZoneMap インデックスを使用してフィルターで除外された行数です。削除条件が含まれます。V1 では、BloomFilter インデックスを使用してフィルターで除外された行数が含まれます。
- RowsConditionsFiltered: 0 # V2 でのみ、さまざまな列インデックスを使用してフィルターで除外された行数です。
- RowsVectorPredFiltered: 0 # ベクトル化された条件に基づくフィルタリング操作を使用してフィルターで除外された行数です。
- TotalPagesNum: 30 # V2 でのみ、読み取られたページの総数です。
- UncompressedBytesRead: 0.00 # V1 では、展開後に読み取られたデータファイルのサイズです。展開が不要な場合、このパラメーターはファイルのサイズを指定します。V2 では、このパラメーターは、展開後にページキャッシュにヒットしなかったページのサイズを指定します。展開が不要な場合、このパラメーターはページのサイズを指定します。
- VectorPredEvalTime: 0ns # ベクトル化された条件によるフィルタリングの実行にかかった時間です。
- ShortPredEvalTime: 0ns # ショートサーキット述語によるフィルタリングの実行にかかった時間です。
- PredColumnReadTime: 0ns # 述語列の読み取りにかかった時間です。
- LazyReadTime: 0ns # 非述語列の読み取りにかかった時間です。
- OutputColumnTime: 0ns # 列のマテリアライズにかかった時間です。
述語条件のプッシュダウンとインデックスの使用状況は、プロファイル内のデータ行数に関連するメトリックから推測できます。次のセクションでは、V2 フォーマットのセグメントの読み取り中のプロファイル情報について説明します。これらのメトリックは、V1 フォーマットのセグメントでは少し異なる意味を持ちます。
初期化フェーズ
V2 フォーマットのセグメントの読み取り中に、クエリに key_ranges(プレフィックスキーで構成されるクエリ範囲)がある場合、最初に SortkeyIndex インデックスを使用してデータがフィルタリングされます。除外された行数は、
RowsKeyRangeFilteredに記録されます。クエリ条件にビットマップインデックスが含まれている場合、ビットマップインデックスを使用して列に対して正確なフィルタリングが実行されます。除外された行数は、
RowsBitmapIndexFilteredに記録されます。BloomFilter インデックスを使用して、クエリ条件の等価
(eq, in, and is)条件に基づいてデータがフィルタリングされます。除外された行数は、RowsBloomFilterFilteredに記録されます。RowsBloomFilterFilteredは、セグメント内の行の総数(ビットマップインデックスによって除外された行の数ではない)と BloomFilter インデックスによるフィルタリング後の残りの行数の差を指定します。そのため、BloomFilter インデックスによってフィルタリングされるデータは、ビットマップインデックスによってフィルタリングされるデータと重複する可能性があります。クエリおよび削除条件に基づいて、ZoneMap インデックスを使用してデータがフィルタリングされます。除外された行数は、
RowsStatsFilteredに記録されます。RowsConditionsFilteredは、RowsBloomFilterFilteredおよびRowsStatsFilteredの値を含む、さまざまなインデックスを使用して除外された行数を指定します。
次のフェーズ
次のフェーズで削除条件を使用して除外される行数は、
RowsDelFilteredに記録されます。削除条件によって実際に除外される行数は、RowsStatsFilteredとRowsDelFilteredに記録されます。RawRowsReadは、先行するフィルタリング操作の実行後に読み取られる行数を指定します。RowsReadは、スキャナに返される行数を指定します。通常、RowsReadの値はRawRowsReadの値よりも小さくなります。これは、ストレージエンジンからスキャナに返されるデータが集計される場合があるためです。RawRowsReadの値とRowsReadの値の差が予想よりも大きい場合は、多数の行が集計されているため、時間がかかる場合があります。RowsReturnedは、ScanNode によって親ノードに最終的に返される行数を指定します。通常、RowsReturnedの値もRowsReadの値よりも小さくなります。一部の述語条件は、スキャナのストレージエンジンにプッシュダウンされません。これは、フィルタリングが実行されていることを示します。RowsReadの値とRowsReturnedの値の差が予想よりも大きい場合は、スキャナで多数の行がフィルタリングされています。これは、選択率の高い複数の述語条件がストレージエンジンにプッシュされていないことを示します。スキャナのフィルタリング効率は、ストレージエンジンのフィルタリング効率よりも低くなります。
上記のメトリクスに基づいて、ストレージエンジンによって処理される行数と、フィルタリング後の最終結果の行数を大まかに分析できます。この一連のメトリクス(Rows***Filtered)を使用すると、クエリ条件がストレージエンジンにプッシュダウンされているかどうか、およびさまざまなインデックスのフィルタリング効果を分析することもできます。
その他のメトリック
また、次のメトリックに基づいて分析を実行することもできます。
OlapScannerの下のメトリクス(IOTimerやBlockFetchTimeなど)は、すべてのスキャナースレッドメトリクスの累積です。そのため、メトリクスの値が比較的大きくなる可能性があります。スキャナースレッドはデータを非同期に読み取ります。この場合、これらの累積メトリクス値は、スキャナーの累積作業時間のみを反映し、ScanNode で消費された時間を直接示すことはできません。実行計画全体における ScanNode で消費された時間の割合は、Activeに記録されます。場合によっては、IOTimerの値が数十秒であるのに対し、Activeの値は数秒のみです。次の項目が原因を示している可能性があります。IOTimerは複数のスキャナーの累積時間であり、多数のスキャナーが使用可能です。親ノードが時間のかかる処理です。たとえば、親ノードが 100 秒を消費するのに対し、ScanNode は 10 秒しか消費しません。
Activeパラメーターの値は数ミリ秒のみである可能性があります。親ノードがデータを処理しているとき、ScanNode はデータを非同期にスキャンしてデータを準備しています。したがって、親ノードは ScanNode で準備されたデータを取得できます。この場合、アクティブ時間は短くなります。
NumScannersは、スキャナーがスレッドプールに送信するタスクの数を示し、RuntimeStateのスレッドプールによってスケジュールされます。doris_scanner_thread_pool_thread_numパラメーターとdoris_scanner_thread_pool_queue_sizeパラメーターは、それぞれスレッドプールのサイズとキューの長さを指定します。スレッドの数が過剰または不足している場合、クエリ効率に影響します。また、一部のメトリクスをスレッド数で割って、各スレッドで消費される時間を大まかに見積もることもできます。TabletCountは、スキャンされるタブレットの数を示します。タブレット数が過剰な場合、多数のランダム読み取り操作とデータマージ操作が必要になることを示します。UncompressedBytesReadは、読み取られるデータのサイズを間接的に反映します。値が大きい場合、多数の I/O 操作が実行される可能性があります。CachedPagesNumとTotalPagesNumに基づいて、ページキャッシュのヒットを確認できます。ヒット率が高いほど、I/O 操作と展開操作に費やす時間が少ないことを示します。
バッファプール
パラメーター | 説明 |
AllocTime | メモリ割り当てに消費された時間。 |
CumulativeAllocationBytes | 累積メモリ割り当てのサイズ。 |
CumulativeAllocations | 累積メモリ割り当て数。 |
PeakReservation | ピーク予約量。 |
PeakUnpinnedBytes | 固定解除されたメモリデータのサイズ。 |
PeakUsedReservation | 予約されたメモリの使用量。 |
ReservationLimit | バッファープールでの予約の制限。 |