クエリの制限
適用対象: ✅Microsoft Fabric✅Azure データ エクスプローラー✅Azure Monitor✅Microsoft Sentinel
Kusto は、大規模なデータセットをホストし、関連するすべてのデータをメモリ内に保持することでクエリを満たそうとするアドホック クエリ エンジンです。 クエリによってサービス リソースが際限なく独占されるという固有のリスクがあります。 Kusto には、既定のクエリ制限という形でいくつかの組み込みの保護が用意されています。 これらの制限を削除することを検討している場合は、まず、その結果として実際に何かメリットがあるかどうかを判断してください。
要求の同時実行に対する制限
要求のコンカレンシー は、同時に実行される複数の要求に適用される制限です。
- 制限の既定値は、データベースが実行されている SKU によって異なり、
Cores-Per-Node x 10
として計算されます。- たとえば、各マシンに 16 個の仮想コアがある D14v2 SKU に設定されているデータベースの場合、既定の制限は
16 cores x10 = 160
。
- たとえば、各マシンに 16 個の仮想コアがある D14v2 SKU に設定されているデータベースの場合、既定の制限は
default
ワークロード グループの要求レート制限ポリシーを構成すると、既定値を変更できます。- データベースで同時に実行できる要求の実際の数は、さまざまな要因によって異なります。 最も重要な要因は、データベース SKU、データベースの使用可能なリソース、および使用パターンです。 ポリシーは、運用環境に似た使用パターンで実行される負荷テストに基づいて構成できます。
詳細については、「Azure Data Explorer を使用した高いコンカレンシーの最適化」を参照してください。
結果セット サイズに対する制限 (結果の切り捨て)
結果の切り捨ては、クエリによって返される結果セットに既定で設定される制限です。 Kusto では、クライアントに返されるレコード数が 500,000 に制限され、そのレコードの全体的なデータ サイズは 64 MB に制限されています。 これらの制限を超えた場合、クエリは "部分的なクエリ エラー" で失敗します。 全体のデータ サイズを超えると、次のメッセージの例外が生成されます。
The Kusto DataEngine has failed to execute a query: 'Query result set has exceeded the internal data size limit 67108864 (E_QUERY_RESULT_SET_TOO_LARGE).'
レコード数を超えると、次のような例外が発生して失敗します。
The Kusto DataEngine has failed to execute a query: 'Query result set has exceeded the internal record count limit 500000 (E_QUERY_RESULT_SET_TOO_LARGE).'
このエラーを処理するには、いくつかの方法があります。
- 必要なデータのみを返すようにクエリを変更することで、結果セットのサイズを小さくします。 この戦略は、最初に失敗したクエリが "広範" である場合に役立ちます。 たとえば、不要なデータ列がクエリに反映されていない場合です。
- 集計など、クエリ後の処理をクエリ自体に移動することで、結果セットのサイズを小さくします。 この戦略は、クエリの出力が別の処理システムに送られ、そこで他の集計が行われるシナリオで役立ちます。
- サービスから大量のデータ セットをエクスポートする場合は、クエリからデータのエクスポートの使用に切り替えます。
- 次に示す
set
ステートメントまたはクライアント要求プロパティのフラグを使用して、このクエリ制限を抑制するようにサービスに指示します。
クエリによって生成される結果セットのサイズを小さくするには、次のような方法があります。
- summarize 演算子グループを使用して、クエリ出力内の類似レコードを集計します。 take_any 集計関数を使用して、いくつかの列をサンプリングすることもできます。
- take 演算子を使用してクエリ出力をサンプリングします。
- substring 関数を使用して、幅の広いフリーテキスト列をトリミングします。
- project 演算子を使用して、結果セットから不要な列を削除します。
notruncation
要求オプションを使用して、結果の切り捨てを無効にすることができます。
ただし、何らかの形式の制限を設定しておくことをお勧めします。
次に例を示します。
set notruncation;
MyTable | take 1000000
truncationmaxsize
(バイト単位の最大データ サイズ、既定値は 64 MB) と truncationmaxrecords
(最大レコード数、既定値は 500,000) の値を設定することで、結果の切り捨てをより細かく制御することもできます。 たとえば、次のクエリでは、1,105 件のレコードまたは 1 MB のいずれかを超えたときに結果の切り捨てが発生するように設定されます。
set truncationmaxsize=1048576;
set truncationmaxrecords=1105;
MyTable | where User=="UserId1"
結果の切り捨て制限を削除することは、大量のデータが Kusto から移動されることを意味します。
結果の切り捨て制限を削除できるのは、.export
コマンドを使用してエクスポートする目的がある場合、または後で集計する場合です。 後で集計する場合は、Kusto を使用して集計することを検討してください。
Kusto には、呼び出し元にストリーミングすることで、"非常に大規模な" 結果を処理できるようにするクライアント ライブラリが多数用意されています。 このようなライブラリのいずれかを使用して、ストリーミング モードに構成します。 たとえば、.NET Framework クライアント (Microsoft.Azure.Kusto.Data) を使用して、接続文字列のストリーミング プロパティを true に設定するか、ExecuteQueryV2Async() の呼び出しを使用して常に結果をストリーミングするようにします。 ExecuteQueryV2Async() の使用方法の例については、HelloKustoV2 アプリケーションを参照してください。
また、C# ストリーミング インジェストのサンプル アプリケーションに関する記事も役に立つ場合があります。
結果の切り捨ては、クライアントに返される結果のストリームだけでなく、既定で適用されます。
また、既定で、あるクラスターから別のクラスターにクロスクラスター クエリで発行されるサブクエリにも適用され、同様の効果があります。
また、既定では、ある Eventhouse がクロスイベントハウス クエリの別の Eventhouse に発行するサブクエリにも、同様の効果が適用されます。
複数の結果の切り捨てプロパティの設定
set
ステートメントを使用する場合、またはクライアント要求のプロパティでフラグを指定する場合は、次のことが適用されます。
notruncation
が設定されて、truncationmaxsize
、truncationmaxrecords
、query_take_max_records
のいずれかも設定されている場合、notruncation
は無視されます。truncationmaxsize
、truncationmaxrecords
またはquery_take_max_records
が複数回設定されている場合は、各プロパティの "小さい" 方の値が適用されます。
クエリ演算子によって消費されるメモリの制限 (E_RUNAWAY_QUERY)
Kusto は、各クエリ演算子が使用できるメモリを制限して、"暴走" クエリから保護します。
この制限は、メモリ内の重要なデータを保持することによって動作する一部のクエリ演算子 ( join
や summarize
など) によって達成される可能性があります。 既定では、制限は 5 GB (ノードあたり) であり、要求オプションを maxmemoryconsumptionperiterator
設定することで増やすことができます。
set maxmemoryconsumptionperiterator=68719476736;
MyTable | summarize count() by Use
この制限に達すると、テキスト E_RUNAWAY_QUERY
を含むメッセージを含む部分的なクエリ エラーが生成されます。
The ClusterBy operator has exceeded the memory budget during evaluation. Results may be incorrect or incomplete E_RUNAWAY_QUERY.
The DemultiplexedResultSetCache operator has exceeded the memory budget during evaluation. Results may be incorrect or incomplete (E_RUNAWAY_QUERY).
The ExecuteAndCache operator has exceeded the memory budget during evaluation. Results may be incorrect or incomplete (E_RUNAWAY_QUERY).
The HashJoin operator has exceeded the memory budget during evaluation. Results may be incorrect or incomplete (E_RUNAWAY_QUERY).
The Sort operator has exceeded the memory budget during evaluation. Results may be incorrect or incomplete (E_RUNAWAY_QUERY).
The Summarize operator has exceeded the memory budget during evaluation. Results may be incorrect or incomplete (E_RUNAWAY_QUERY).
The TopNestedAggregator operator has exceeded the memory budget during evaluation. Results may be incorrect or incomplete (E_RUNAWAY_QUERY).
The TopNested operator has exceeded the memory budget during evaluation. Results may be incorrect or incomplete (E_RUNAWAY_QUERY).
maxmemoryconsumptionperiterator
が複数回設定されている場合 (たとえばクライアント要求のプロパティと set
ステートメントの両方を使用)、低い方の値が適用されます。
E_RUNAWAY_QUERY
部分的なクエリエラーを引き起こす可能性のある追加の制限は、1 つの演算子が保持する文字列の最大累積サイズの制限です。 この制限は、上記の要求オプションではオーバーライドできません。
Runaway query (E_RUNAWAY_QUERY). Aggregation over string column exceeded the memory budget of 8GB during evaluation.
この制限を超えた場合、最も可能性の高いクエリ演算子は、 join
、 summarize
、または make-series
です。
この制限を回避するには、 シャッフレ クエリ 戦略を使用するようにクエリを変更する必要があります。
(これは、クエリのパフォーマンスを向上させる可能性もあります)。
E_RUNAWAY_QUERY
のすべての場合、追加のオプション (要求オプションを設定し、シャッフル戦略を使用するようにクエリを変更することによって制限を増やす以外) は、サンプリングに切り替えることです。
次の 2 つのクエリは、サンプリングの実行方法を示しています。 1 つ目のクエリは、乱数ジェネレーターを使用した統計サンプリングです。 2 番目のクエリは確定的なサンプリングであり、データセットからいくつかの列 (通常は一部の ID) をハッシュすることによって実行されます。
T | where rand() < 0.1 | ...
T | where hash(UserId, 10) == 1 | ...
ノードあたりのメモリに対する制限
ノードあたりのクエリあたりの最大メモリは、"暴走" クエリから保護するために使用されるもう 1 つの制限です。 この制限は要求オプション max_memory_consumption_per_query_per_node
で表され、特定のクエリに対して 1 つノードで使用できるメモリ量の上限が設定されます。
set max_memory_consumption_per_query_per_node=68719476736;
MyTable | ...
max_memory_consumption_per_query_per_node
が複数回設定されている場合 (たとえばクライアント要求のプロパティと set
ステートメントの両方を使用)、低い方の値が適用されます。
クエリで summarize
、join
、または make-series
演算子が使用されている場合は、クエリのシャッフル戦略を使用して、1 台のコンピューターのメモリの負荷を軽減できます。
実行タイムアウトの制限
サーバー タイムアウトは、すべての要求に適用されるサービス側のタイムアウトです。 実行中の要求 (クエリと管理コマンド) のタイムアウトは、Kusto 内の複数のポイントで適用されます。
- クライアント ライブラリ (使用されている場合)
- 要求を受け入れるサービス エンドポイント
- 要求を処理するサービス エンジン
既定では、クエリの場合はタイムアウトが 4 分、管理コマンドの場合は 10 分に設定されます。 この値は、必要に応じて増やすことができます (上限は 1 時間)。
- さまざまなクライアント ツールで、グローバルな設定または接続ごとの設定の一部として、タイムアウトの変更がサポートされています。 たとえば、Kusto.Explorer で、[ツール]>[オプション]* >[接続]>[クエリ サーバーのタイムアウト] を使用します。
- SDK は、プログラムによって
servertimeout
プロパティによるタイムアウトの設定をサポートします。 たとえば、.NET SDK では、クライアント要求のプロパティで、System.TimeSpan
型の値を設定してサポートされます。
タイムアウトに関する注意事項
- クライアント側では、作成された要求から応答がクライアントに到着し始めるまでのタイムアウトが適用されます。 クライアントでペイロードの読み取りにかかる時間は、タイムアウトの一部として扱われません。 これは、呼び出し元がストリームからデータをプルする速度によって変わります。
- また、クライアント側では、使用される実際のタイムアウト値は、ユーザーが要求したサーバー タイムアウト値よりもわずかに高くなります。 ネットワークの待機時間を考慮に入れるために、この差があります。
- 最大許容要求タイムアウトを自動的に使用するには、クライアント要求プロパティ
norequesttimeout
をtrue
に設定します。
Note
Azure Data Explorer Web UI、Kusto.Explorer、Kusto.Cli、Power BI でタイムアウトを設定する方法と SDK を使用する場合の詳細なガイドについては、「 設定タイムアウト制限 を参照してください。
クエリの CPU リソース使用率に対する制限
Kusto を使用すると、クエリを実行し、データベースに含まれる使用可能なすべての CPU リソースを使用できます。 複数のクエリが実行されている場合は、クエリ間で公平なラウンド ロビンが試行されます。 このメソッドは、クエリ定義関数に最適なパフォーマンスを実現します。 また、特定のクエリに使用される CPU リソースを制限する場合もあります。 たとえば、"バックグラウンド ジョブ" を実行すると、同時実行インライン クエリの優先度が高くなるように、待機時間が長くなる可能性があります。
Kusto では、クエリの実行時に 2 つのrequest プロパティの指定がサポートされています。 そのプロパティは、query_fanout_threads_percent と query_fanout_nodes_percent です。 どちらのプロパティも既定値は最大値 (100) の整数ですが、クエリによっては他の値に減らすこともできます。
1 つ目 query_fanout_threads_percent を使用すると、スレッドの使用に対するファンアウト係数を制御できます。 このプロパティを 100% に設定すると、すべての CPU が各ノードに割り当てられます。 たとえば、Azure D14 ノードにデプロイされた 16 個の CPU などです。 このプロパティが 50% に設定されている場合は CPU の半分が使用されます。その他の値も同様です。 数値は CPU 全体に切り上げられるため、プロパティ値を 0 に設定しても問題ありません。
2 つ目の query_fanout_nodes_percentでは、サブクエリ分散操作ごとに使用するクエリ ノードの数を制御します。 機能は同様です。
query_fanout_nodes_percent
または query_fanout_threads_percent
が複数回設定されている場合 (たとえばクライアント要求のプロパティと set
ステートメントの両方を使用)、各プロパティの低い方の値が適用されます。
クエリの複雑さに対する制限
クエリの実行時に、クエリ テキストはクエリを表す関係演算子のツリーに変換されます。 ツリーの深さが内部しきい値を超えると、複雑すぎて処理できないクエリと見なされて失敗し、エラー コードが返されます。 このエラーは、関係演算子ツリーが制限を超えていることを示します。
次の例は、クエリがこの制限を超えて失敗する可能性がある一般的なクエリ パターンを示しています。
- 一緒に連結される二項演算子の長いリスト。 次に例を示します。
T
| where Column == "value1" or
Column == "value2" or
.... or
Column == "valueN"
この特定のケースでは、in()
演算子を使用してクエリを書き直してください。
T
| where Column in ("value1", "value2".... "valueN")
- 非常に広いスキーマ分析を実行している共用体演算子を持つクエリ。特に、共用体の既定のフレーバーは "外部" 共用体スキーマを返すということです (つまり、出力には基になるテーブルのすべての列が含まれます)。
この場合、クエリを見直し、クエリで使用されている列を減らすことをお勧めします。