Azure Monitor でログ クエリを最適化するOptimize log queries in Azure Monitor

Azure Monitor ログでは、Azure Data Explorer (ADX) を使用して、ログ データを格納し、そのデータを分析するためのクエリを実行します。Azure Monitor Logs uses Azure Data Explorer (ADX) to store log data and run queries for analyzing that data. これにより、ADX クラスターが作成、管理、保持され、ログ分析ワークロードに合わせて最適化されます。It creates, manages, and maintains the ADX clusters for you, and optimizes them for your log analysis workload. クエリを実行すると、クエリが最適化され、ワークスペース データを格納する適切な ADX クラスターにルーティングされます。When you run a query, it's optimized, and routed to the appropriate ADX cluster that stores the workspace data. Azure Monitor ログと Azure Data Explorer のどちらにも、クエリの自動最適化メカニズムが多数使用されています。Both Azure Monitor Logs and Azure Data Explorer uses many automatic query optimization mechanisms. 自動最適化によって大幅に処理が促進される一方で、クエリのパフォーマンスを飛躍的に向上させることができるケースもいくつかあります。While automatic optimizations provide significant boost, there are some cases where you can dramatically improve your query performance. この記事では、パフォーマンスに関する考慮事項とそれを調整するいくつかの手法について説明します。This article explains the performance considerations and several techniques to fix them.

その手法の大半は、Azure Data Explorer と Azure Monitor ログに対して直接実行されるクエリに共通しますが、ここでは Azure Monitor ログに固有の考慮事項をいくつか取り上げます。Most of the techniques are common to queries that are run directly on Azure Data Explorer and Azure Monitor Logs, though there are several unique Azure Monitor Logs considerations that are discussed here. Azure Data Explorer の最適化に関するヒントについては、「クエリのベスト プラクティス」を参照してください。For more Azure Data Explorer optimization tips, see Query best practices.

最適化されたクエリは次のようになります。Optimized queries will:

  • 実行速度が上がり、クエリ実行全体の期間が短縮されます。Run faster, reduce overall duration of the query execution.
  • スロットルまたは拒否される可能性が低くなります。Have smaller chance of being throttled or rejected.

ダッシュボード、アラート、Logic Apps、Power BI など、繰り返し集中的に使用されるクエリには、特に注意を払う必要があります。You should give particular attention to queries that are used for recurrent and bursty usage such as dashboards, alerts, Logic Apps and Power BI. このような場合に効果のないクエリが及ぼす影響はかなり大きくなります。The impact of an ineffective query in these cases is substantial.

クエリ パフォーマンス ペインQuery performance pane

Log Analytics でクエリを実行した後、クエリ結果の上にある下矢印をクリックすると、クエリ パフォーマンス ペインが表示されます。ここには、クエリのいくつかのパフォーマンス指標の結果が示されます。After you run a query in Log Analytics, click the down arrow above the query results to view the query performance pane that shows the results of several performance indicators for the query. これらの各パフォーマンス指標については、次のセクションで説明します。These performance indicators are each described in the following section.

クエリ パフォーマンス ペイン

クエリ パフォーマンス指標Query performance indicators

実行されるクエリごとに、次のクエリ パフォーマンス指標を使用できます。The following query performance indicators are available for every query that is executed:

  • [合計 CPU]: すべての計算ノードでクエリを処理するために使用された全体的な計算。Total CPU: Overall compute used to process the query across all compute nodes. これは、計算、解析、データの取得に使用された時間を表します。It represents time used for computing, parsing, and data fetching.

  • [処理されたクエリに使用するデータ]: クエリを処理するためにアクセスされたデータ全体。Data used for processed query: Overall data that was accessed to process the query. 対象のテーブルのサイズ、使用された期間、適用されたフィルター、参照されている列の数の影響を受けます。Influenced by the size of the target table, time span used, filters applied, and the number of columns referenced.

  • [処理されたクエリの期間]: クエリを処理するためにアクセスされた最新データと最も古いデータの差分。Time span of the processed query: The gap between the newest and the oldest data that was accessed to process the query. クエリに指定された明示的な時間の範囲の影響を受けます。Influenced by the explicit time range specified for the query.

  • [処理されたデータの期間]: 現在と、クエリを処理するためにアクセスされた最も古いデータの差分。Age of processed data: The gap between now and the oldest data that was accessed to process the query. これは、データの取得の効率に大きく影響します。It highly influences the efficiency of data fetching.

  • [ワークスペースの数]: 暗黙的または明示的な選択によってクエリ処理中にアクセスされたワークスペースの数。Number of workspaces: How many workspaces were accessed during the query processing due to implicit or explicit selection.

  • [リージョンの数]: 暗黙的または明示的なワークスペースの選択によってクエリ処理中にアクセスされたリージョンの数。Number of regions: How many regions were accessed during the query processing based due to implicit or explicit selection of workspaces. 複数リージョンのクエリでは効率がかなり低下し、パフォーマンス指標は部分的にしかカバーしなくなります。Multi-region queries are much less efficient and performance indicators present partial coverage.

  • [並行処理]:システムにより、このクエリをどの程度、複数ノードで実行できたかを示します。Parallelism: Indicates how much the system was able to execute this query on multiple nodes. CPU 使用率が高いクエリにのみ関連します。Relevant only to queries that have high CPU consumption. 特定の関数と演算子の使用による影響を受けます。Influenced by usage of specific functions and operators.

合計 CPUTotal CPU

すべてのクエリ処理ノードでこのクエリを処理するために実際に投入されたコンピューティング CPU です。The actual compute CPU that was invested to process this query across all the query processing nodes. ほとんどのクエリは多数のノード上で実行されるため、通常、これはクエリの実行に実際にかかった期間よりもはるかに大きくなります。Since most queries are executed on large numbers of nodes, this will usually be much larger than the duration the query actually took to execute.

CPU を 100 秒以上活用するクリエは、リソースを過度に消費するクエリと見なされます。Query that utilizes more than 100 seconds of CPU is considered a query that consumes excessive resources. CPU を 1,000 秒以上活用するクリエはリソースを酷使するクエリと見なされ、調整されることがあります。Query that utilizes more than 1,000 seconds of CPU is considered an abusive query and might be throttled.

クエリの処理時間は以下に費やされます。Query processing time is spent on:

  • データ取得 - 古いデータの取得には、最近のデータの取得よりも時間がかかります。Data retrieval – retrieval of old data will consume more time than retrieval of recent data.
  • データ処理 - データのロジックと評価。Data processing – logic and evaluation of the data.

クエリ処理ノードでかかった時間以外にも、ユーザーの認証とそのユーザーがこのデータにアクセスできることの確認、データ ストアの特定、クエリの解析、クエリ処理ノードの割り当てのために Azure Monitor ログではさらに時間が費やされます。Other than time spent in the query processing nodes, there is additional time that is spend by Azure Monitor Logs to: authenticate the user and verify that they are permitted to access this data, locate the data store, parse the query, and allocate the query processing nodes. この時間は、クエリの合計 CPU 時間には含まれません。This time is not included in the query total CPU time.

CPU 使用率の高い関数を使用する前にレコードを初期フィルター処理するEarly filtering of records prior of using high CPU functions

クエリのコマンドと関数の中には、CPU 使用率の高いものがあります。Some of the query commands and functions are heavy in their CPU consumption. これは特に、JSON と XML の解析や複雑な正規表現の抽出を実行するコマンドに当てはまります。This is especially true for commands that parse JSON and XML or extract complex regular expressions. このような解析は、parse_json () または parse_xml () 関数で明示的に行われることもあれば、動的な列の参照時に暗黙的に行われることもあります。Such parsing can happen explicitly via parse_json() or parse_xml() functions or implicitly when referring to dynamic columns.

これらの関数では、処理対象の行数に比例して CPU が消費されます。These functions consume CPU in proportion to the number of rows they are processing. 最も効率的な最適化では、CPU を集中的に使用する関数が実行される前にできるだけ多くのレコードを除外できる where 条件を、クエリ内の初期段階で追加します。The most efficient optimization is to add where conditions early in the query that can filter out as many records as possible before the CPU intensive function is executed.

たとえば、次のクエリではまったく同じ結果が得られますが、2 番目のクエリは、解析前の where 条件によって多くのレコードが除外されるためはるかに効率的になります。For example, the following queries produce exactly the same result but the second one is by far the most efficient as the where condition before parsing excludes many records:

//less efficient
SecurityEvent
| extend Details = parse_xml(EventData)
| extend FilePath = tostring(Details.UserData.RuleAndFileData.FilePath)
| extend FileHash = tostring(Details.UserData.RuleAndFileData.FileHash)
| where FileHash != "" and FilePath !startswith "%SYSTEM32"  // Problem: irrelevant results are filtered after all processing and parsing is done
| summarize count() by FileHash, FilePath
//more efficient
SecurityEvent
| where EventID == 8002 //Only this event have FileHash
| where EventData !has "%SYSTEM32" //Early removal of unwanted records
| extend Details = parse_xml(EventData)
| extend FilePath = tostring(Details.UserData.RuleAndFileData.FilePath)
| extend FileHash = tostring(Details.UserData.RuleAndFileData.FileHash)
| where FileHash != "" and FilePath !startswith "%SYSTEM32"  // exact removal of results. Early filter is not accurate enough
| summarize count() by FileHash, FilePath
| where FileHash != "" // No need to filter out %SYSTEM32 here as it was removed before

評価済みの where 句を使用しないAvoid using evaluated where clauses

データセットに物理的に存在する列ではなく、評価済みの列に where 句が配置されているクエリでは、効率が低下します。Queries that contain where clauses on an evaluated column rather than on columns that are physically present in the dataset lose efficiency. 大規模なデータ セットを処理する場合、評価済みの列に対してフィルター処理を行ってもシステムは最適化されない場合があります。Filtering on evaluated columns prevents some system optimizations when large sets of data are handled. たとえば、次のクエリではまったく同じ結果が得られますが、where 条件が組み込み列を参照するため、2 番目のクエリの方が効率的です。For example, the following queries produce exactly the same result but the second one is more efficient as the where condition refers to built-in column

//less efficient
Syslog
| extend Msg = strcat("Syslog: ",SyslogMessage)
| where  Msg  has "Error"
| count 
//more efficient
Syslog
| where  SyslogMessage  has "Error"
| count 

場合によっては、フィルター処理が行われる対象はフィールドだけではないため、評価済みの列がクエリ処理エンジンによって暗黙的に作成されます。In some cases the evaluated column is created implicitly by the query processing engine since the filtering is done not just on the field:

//less efficient
SecurityEvent
| where tolower(Process) == "conhost.exe"
| count 
//more efficient
SecurityEvent
| where Process =~ "conhost.exe"
| count 

効果的な集計コマンドおよびディメンションを summarize と join で使用するUse effective aggregation commands and dimensions in summarize and join

max()sum()count()avg() などの集計コマンドには、そのロジックにより CPU への影響は小さくなるものもありますが、より複雑で、効率的な実行を可能にするヒューリスティックや推定が含まれるものもあります。While some aggregation commands like max(), sum(), count(), and avg() have low CPU impact due to their logic, other are more complex and include heuristics and estimations that allow them to be executed efficiently. たとえば、dcount () では、HyperLogLog アルゴリズムを使用することで、各値を実際にカウントすることなく、大規模なデータ セットの個別カウントに近い推定値が提供されます。また、パーセンタイル関数は、最も近いランク パーセンタイル アルゴリズムを使用して同様の概算を行います。For example, dcount() uses the HyperLogLog algorithm to provide close estimation to distinct count of large sets of data without actually counting each value; the percentile functions are doing similar approximations using the nearest rank percentile algorithm. コマンドのいくつかには、影響を軽減するための省略可能なパラメーターが含まれています。Several of the commands include optional parameters to reduce their impact. たとえば、makeset () 関数には、CPU とメモリに大きく影響する、最大セット サイズを定義するための省略可能なパラメーターがあります。For example, the makeset() function has an optional parameter to define the maximum set size, which significantly affects the CPU and memory.

join および summarize コマンドを使用すると、大規模なデータ セットを処理する際に CPU 使用率が高くなる可能性があります。Join and summarize commands may cause high CPU utilization when they are processing a large set of data. これらの複雑さは、summarize 内で by として使用されている列または join 属性として使用されている列に指定可能な値の数 ("カーディナリティ" と呼ばれます) に直接関連しています。Their complexity is directly related to the number of possible values, referred to as cardinality, of the columns that are using as the by in summarize or as the join attributes. join および summarize の説明と最適化については、それぞれのドキュメント記事と最適化のヒントを参照してください。For explanation and optimization of join and summarize, see their documentation articles and optimization tips.

たとえば、次のクエリでは、CounterPath が常に 1 対 1 で CounterName および ObjectName にマップされるため、まったく同じ結果が得られます。For example, the following queries produce exactly the same result because CounterPath is always one-to-one mapped to CounterName and ObjectName. 2 番目のクエリは、集計ディメンションが小さくなるにつれて、効率が高まります。The second one is more efficient as the aggregation dimension is smaller:

//less efficient
Perf
| summarize avg(CounterValue) 
by CounterName, CounterPath, ObjectName
//make the group expression more compact improve the performance
Perf
| summarize avg(CounterValue), any(CounterName), any(ObjectName) 
by CounterPath

CPU 使用率は、集中的なコンピューティングを必要とする where 条件や拡張列による影響を受ける可能性もあります。CPU consumption might also be impacted by where conditions or extended columns that require intensive computing. equal ==startswith などの単純な文字列比較では CPU への影響がほぼ変わらないのに対して、高度なテキスト一致では影響が大きくなります。All trivial string comparisons such as equal == and startswith have roughly the same CPU impact while advanced text matches have more impact. 具体的には、has 演算子は contains 演算子よりも効率的です。Specifically, the has operator is more efficient that the contains operator. 文字列処理の手法が原因で、短い文字列よりも 4 文字を超える文字列を検索する方が効率的となります。Due to string handling techniques, it is more efficient to look for strings that are longer than four characters than short strings.

たとえば、次のクエリでは、コンピューターの名前付けポリシーに応じて、同様の結果が得られますが、2 番目のクエリの方が効率的です。For example, the following queries produce similar results, depending on Computer naming policy, but the second one is more efficient:

//less efficient – due to filter based on contains
Heartbeat
| where Computer contains "Production" 
| summarize count() by ComputerIP 
//less efficient – due to filter based on extend
Heartbeat
| extend MyComputer = Computer
| where MyComputer startswith "Production" 
| summarize count() by ComputerIP 
//more efficient
Heartbeat
| where Computer startswith "Production" 
| summarize count() by ComputerIP 

注意

この指標は、直近のクラスターの CPU のみを示します。This indicator presents only CPU from the immediate cluster. 複数リージョンのクエリでは、リージョンのうち 1 つだけが表示されます。In multi-region query, it would represent only one of the regions. マルチワークスペース クエリでは、一部のワークスペースが含まれない場合があります。In multi-workspace query, it might not include all workspaces.

文字列解析が機能する場合は XML と JSON をフル解析しないAvoid full XML and JSON parsing when string parsing works

XML または JSON オブジェクトのフル解析は、CPU およびメモリ リソースを多く消費する場合があります。Full parsing of an XML or JSON object may consume high CPU and memory resources. 必要なパラメーターが 1 つか 2 つだけで、XML または JSON オブジェクトが単純である場合、解析演算子またはその他のテキスト解析手法を使い、文字列としてオブジェクトを解析した方が、多くの場合は簡単です。In many cases, when only one or two parameters are needed and the XML or JSON objects are simple, it is easier to parse them as strings using the parse operator or other text parsing techniques. XML または JSON オブジェクト内のレコード数が多いほど、パフォーマンスの向上が顕著になります。The performance boost will be more significant as the number of records in the XML or JSON object increases. レコード数が千万単位に達する場合、これは非常に重要です。It is essential when the number of records reaches tens of millions.

たとえば次のクエリは、フル XML 解析を実行せずに上記のクエリとまったく同じ結果を返します。For example, the following query will return exactly the same results as the queries above without performing full XML parsing. FilePath 要素が FileHash の後にあってどちらの要素も属性を持たないなど、XML ファイルの構造にいくつかの前提条件があることに注意してください。Note that it makes some assumptions on the XML file structure such as that FilePath element comes after FileHash and none of them has attributes.

//even more efficient
SecurityEvent
| where EventID == 8002 //Only this event have FileHash
| where EventData !has "%SYSTEM32" //Early removal of unwanted records
| parse EventData with * "<FilePath>" FilePath "</FilePath>" * "<FileHash>" FileHash "</FileHash>" *
| summarize count() by FileHash, FilePath
| where FileHash != "" // No need to filter out %SYSTEM32 here as it was removed before

処理されたクエリに使用するデータData used for processed query

クエリの処理における重要な要因は、クエリ処理のためにスキャン、使用されるデータの量です。A critical factor in the processing of the query is the volume of data that is scanned and used for the query processing. Azure Data Explorer では、他のデータ プラットフォームと比べ、データ量を大幅に削減する積極的な最適化が使用されています。Azure Data Explorer uses aggressive optimizations that dramatically reduce the data volume compared to other data platforms. それでも、クエリには、使用されるデータ量に影響を与える可能性のある重要な要因があります。Still, there are critical factors in the query that can impact the data volume that is used.

2,000KB を超えるデータを処理するクリエは、リソースを過度に消費するクエリと見なされます。Query that processes more than 2,000KB of data is considered a query that consumes excessive resources. 20,000KB を超えるデータを処理するクリエはリソースを酷使するクエリと見なされ、調整されることがあります。Query that is processing more than 20,000KB of data is considered an abusive query and might be throttled.

Azure Monitor ログでは、データにインデックスを付ける手段として、TimeGenerated 列が使用されます。In Azure Monitor Logs, the TimeGenerated column is used as a way to index the data. TimeGenerated の値をできるだけ狭い範囲に絞り込むと、処理すべきデータの量がかなり制限されることで、クエリのパフォーマンスが大幅に向上します。Restricting the TimeGenerated values to as narrow a range as possible will make a significant improvement to query performance by significantly limiting the amount of data that has to be processed.

検索および和集合演算子を不必要に使わないAvoid unnecessary use of search and union operators

処理するデータが増加するもう 1 つの要因は、多数のテーブルの使用です。Another factor that increases the data that is process is the use of large number of tables. これは通常、search * および union * コマンドの使用時に発生します。This usually happens when search * and union * commands are used. これらのコマンドを実行すると、システムでは、強制的にワークスペース内のすべてのテーブルのデータが評価され、スキャンされます。These commands force the system to evaluate and scan data from all tables in the workspace. 場合によっては、ワークスペース内には数百ものテーブルが存在することがあります。In some cases, there might be hundreds of tables in the workspace. "search *" の使用や、範囲に特定のテーブルを指定しない検索は、できる限り避けるようにしてください。Try to avoid as much as possible using "search *" or any search without scoping it to a specific table.

たとえば、次のクエリではまったく同じ結果が得られますが、最後が最も効率的です。For example, the following queries produce exactly the same result but the last one is by far the most efficient:

// This version scans all tables though only Perf has this kind of data
search "Processor Time" 
| summarize count(), avg(CounterValue)  by Computer
// This version scans all strings in Perf tables – much more efficient
Perf
| search "Processor Time" 
| summarize count(), avg(CounterValue)  by Computer
// This is the most efficient version 
Perf 
| where CounterName == "% Processor Time"  
| summarize count(), avg(CounterValue)  by Computer

初期フィルターをクエリに追加するAdd early filters to the query

データ量を削減するもう 1 つの方法として、クエリの初期段階で where 条件を使用します。Another method to reduce the data volume is to have where conditions early in the query. Azure Data Explorer プラットフォームには、特定の where 条件に関連するデータを含むパーティションを認識できるようにするキャッシュが含まれています。The Azure Data Explorer platform includes a cache that lets it know which partitions include data that is relevant for a specific where condition. たとえば、クエリに where EventID == 4624 が含まれている場合、一致するイベントが含まれるパーティションを処理するノードにのみクエリが分散されます。For example, if a query contains where EventID == 4624 then it would distribute the query only to nodes that handle partitions with matching events.

次のクエリ例ではまったく同じ結果が得られますが、2 番目の方が効率的です。The following example queries produce exactly the same result but the second one is more efficient:

//less efficient
SecurityEvent
| summarize LoginSessions = dcount(LogonGuid) by Account
//more efficient
SecurityEvent
| where EventID == 4624 //Logon GUID is relevant only for logon event
| summarize LoginSessions = dcount(LogonGuid) by Account

条件付き集計関数および materialize 関数を使用して同じソース データの複数スキャンを回避するAvoid multiple scans of same source data using conditional aggregation functions and materialize function

join 演算子または union 演算子を使用してマージされた複数のサブクエリがクエリに含まれている場合、各サブクエリによってソース全体が個別にスキャンされ、結果がマージされます。When a query has several sub-queries that are merged using join or union operators, each sub-query scans the entire source separately and then merge the results. これにより、データがスキャンされる回数が倍増します。これは、非常に大きなデータセットにおいて重要な要素です。This multiples the number of times data is scanned - critical factor in very large data sets.

これを回避する方法としては、条件付き集計関数を使用します。A technique to avoid this is by using the conditional aggregation functions. summary 演算子で使用される集計関数の大部分には、条件付きのバージョンがあります。これにより、複数の条件を持つ単一の summarize 演算子を使用できます。Most of the aggregation functions that are used in summary operator has a conditioned version that allow you to use a single summarize operator with multiple conditions.

たとえば、次のクエリは、ログイン イベントの数と各アカウントのプロセス実行イベントの数を示しています。For example, the following queries show the number of login events and the number of process execution events for each account. 同じ結果が返されますが、前者ではデータが 2 回スキャンされ、後者では 1 回だけスキャンされます。They return the same results but the first is scanning the data twice, the second scan it only once:

//Scans the SecurityEvent table twice and perform expensive join
SecurityEvent
| where EventID == 4624 //Login event
| summarize LoginCount = count() by Account
| join 
(
    SecurityEvent
    | where EventID == 4688 //Process execution event
    | summarize ExecutionCount = count(), ExecutedProcesses = make_set(Process) by Account
) on Account
//Scan only once with no join
SecurityEvent
| where EventID == 4624 or EventID == 4688 //early filter
| summarize LoginCount = countif(EventID == 4624), ExecutionCount = countif(EventID == 4688), ExecutedProcesses = make_set_if(Process,EventID == 4688)  by Account

サブクエリが不要なもう 1 つのケースは、特定のパターンに一致するレコードのみを処理するように parse 演算子を事前フィルター処理する場合です。Another case where sub-queries are unnecessary is pre-filtering for parse operator to make sure that it processes only records that match specific pattern. これは、パターンが一致しない場合、parse 演算子およびその他の同様の演算子によって空の結果が返されるため、不要です。This is unnecessary as the parse operator and other similar operators return empty results when the pattern doesn't match. 次の 2 つのクエリでは、まったく同じ結果が返されますが、2 番目のクエリではデータが 1 回だけスキャンされます。Here are two queries that return exactly the same results while the second query scan data only once. 2 番目のクエリでは、各 parse コマンドはそのイベントのみに関連しています。In the second query, each parse command is relevant only for its events. その後の extend 演算子は、空のデータ状況を参照する方法を示しています。The extend operator afterwards shows how to refer to empty data situation.

//Scan SecurityEvent table twice
union(
SecurityEvent
| where EventID == 8002 
| parse EventData with * "<FilePath>" FilePath "</FilePath>" * "<FileHash>" FileHash "</FileHash>" *
| distinct FilePath
),(
SecurityEvent
| where EventID == 4799
| parse EventData with * "CallerProcessName\">" CallerProcessName1 "</Data>" * 
| distinct CallerProcessName1
)
//Single scan of the SecurityEvent table
SecurityEvent
| where EventID == 8002 or EventID == 4799
| parse EventData with * "<FilePath>" FilePath "</FilePath>" * "<FileHash>" FileHash "</FileHash>" * //Relevant only for event 8002
| parse EventData with * "CallerProcessName\">" CallerProcessName1 "</Data>" *  //Relevant only for event 4799
| extend FilePath = iif(isempty(CallerProcessName1),FilePath,"")
| distinct FilePath, CallerProcessName1

上の例でサブクエリの使用を回避できない場合は、別の方法として materialize() 関数を使用して、それぞれに使用される単一のソース データが存在することについてクエリ エンジンにヒントを提供します。When the above doesn't allow to avoid using sub-queries, another technique is to hint to the query engine that there is a single source data used in each one of them using the materialize() function. これは、クエリ内で複数回使用される関数からソース データが取得される場合に便利です。This is useful when the source data is coming from a function that is used several times within the query. materialize は、サブクエリの出力が入力よりもはるかに小さい場合に有効です。Materialize is effective when the output of the sub-query is much smaller than the input. クエリ エンジンによって、すべての発生において出力がキャッシュされ再利用されます。The query engine will cache and reuse the output in all occurrences.

取得する列の数を減らすReduce the number of columns that is retrieved

Azure Data Explorer は列形式のデータ ストアであるため、各列の取得は他の列とは関係がありません。Since Azure Data Explorer is a columnar data store, retrieval of every column is independent of the others. 取得される列の数は、全体のデータ量に直接影響します。The number of columns that are retrieved directly influences the overall data volume. 結果を集計したり、特定の列を射影したりすることで、必要な列のみを出力に含める必要があります。You should only include the columns in the output that are needed by summarizing the results or projecting the specific columns. Azure Data Explorer には、取得される列の数を減らすために複数の最適化を行っています。Azure Data Explorer has several optimizations to reduce the number of retrieved columns. ある列が不要であると判断された場合 (たとえば、summarize コマンドで参照されていない場合)、その列は取得されません。If it determines that a column isn't needed, for example if it's not referenced in the summarize command, it won't retrieve it.

たとえば、2 番目のクエリでは、1 つの列ではなく 3 つの列を取得する必要があるため、処理するデータが 3 倍になる可能性があります。For example, the second query may process three times more data since it needs to fetch not one column but three:

//Less columns --> Less data
SecurityEvent
| summarize count() by Computer  
//More columns --> More data
SecurityEvent
| summarize count(), dcount(EventID), avg(Level) by Computer  

処理されたクエリの期間Time span of the processed query

Azure Monitor ログ内のすべてのログは、TimeGenerated 列に従ってパーティション分割されます。All logs in Azure Monitor Logs are partitioned according to the TimeGenerated column. アクセスされるパーティションの数は、期間に直接関係します。The number of partitions that are accessed are directly related to the time span. 時間範囲を短縮することは、迅速なクエリ実行を確実にするための最も効率的な方法となります。Reducing the time range is the most efficient way of assuring a prompt query execution.

期間が 15 日間を超えるクエリは、リソースを過度に消費するクエリと見なされます。Query with time span of more than 15 days is considered a query that consumes excessive resources. 期間が 90 日間を超えるクエリはリソースを酷使するクエリと見なされ、調整されることがあります。Query with time span of more than 90 days is considered an abusive query and might be throttled.

時間範囲は、「Azure Monitor Log Analytics のログ クエリのスコープと時間範囲」で説明されているように、Log Analytics 画面で時間範囲セレクターを使用して設定できます。The time range can be set using the time range selector in the Log Analytics screen as described in Log query scope and time range in Azure Monitor Log Analytics. 選択した時間範囲がクエリ メタデータを使用してバックエンドに渡されるため、この方法をお勧めします。This is the recommended method as the selected time range is passed to the backend using the query metadata.

別の方法として、クエリの TimeGeneratedwhere 条件を明示的に含めることもできます。An alternative method is to explicitly include a where condition on TimeGenerated in the query. この方法を使用すると、クエリが別のインターフェイスから使用される場合でも、期間が確実に固定されます。You should use this method as it assures that the time span is fixed, even when the query is used from a different interface. クエリのすべての要素には必ず TimeGenerated フィルターを指定する必要があります。You should ensure that all parts of the query have TimeGenerated filters. 複数のテーブルまたは同じテーブルからデータを取得するサブクエリがクエリに含まれている場合、それぞれに独自の where 条件を含める必要があります。When a query has sub-queries fetching data from various tables or the same table, each has to include its own where condition.

すべてのサブクエリに TimeGenerated フィルターがあることを確認するMake sure all sub-queries have TimeGenerated filter

たとえば、次のクエリでは、Perf テーブルで最終日のみがスキャンされますが、Heartbeat テーブルではその履歴すべて (最大 2 年間の場合があります) がスキャンされます。For example, in the following query, while the Perf table will be scanned only for the last day, the Heartbeat table will be scanned for all of its history, which might be up to two years:

Perf
| where TimeGenerated > ago(1d)
| summarize avg(CounterValue) by Computer, CounterName
| join kind=leftouter (
    Heartbeat
    //No time span filter in this part of the query
    | summarize IPs = makeset(ComputerIP, 10) by  Computer
) on Computer

このような誤りが発生する一般的なケースとして、直近の出現箇所の検索に arg_max () が使用されている場合が挙げられます。A common case where such a mistake occurs is when arg_max() is used to find the most recent occurrence. 次に例を示します。For example:

Perf
| where TimeGenerated > ago(1d)
| summarize avg(CounterValue) by Computer, CounterName
| join kind=leftouter (
    Heartbeat
    //No time span filter in this part of the query
    | summarize arg_max(TimeGenerated, *), min(TimeGenerated)   
by Computer
) on Computer

これは、次のように、内部クエリに時間フィルターを追加することで簡単に修正できます。This can be easily corrected by adding a time filter in the inner query:

Perf
| where TimeGenerated > ago(1d)
| summarize avg(CounterValue) by Computer, CounterName
| join kind=leftouter (
    Heartbeat
    | where TimeGenerated > ago(1d) //filter for this part
    | summarize arg_max(TimeGenerated, *), min(TimeGenerated)   
by Computer
) on Computer

このエラーのもう 1 つの例は、複数のテーブルに対する union の直後に時間範囲フィルターを実行する場合です。Another example for this fault is when performing the time scope filtering just after a union over several tables. union を実行する場合、各サブクエリの範囲を設定する必要があります。When performing the union, each sub-query should be scoped. let ステートメントを使用して、範囲の一貫性を確保することができます。You can use let statement to assure scoping consistency.

たとえば、次のクエリは Heartbeat テーブルと Perf テーブル内で、過去 1 日分だけでなくすべてのデータをスキャンします。For example, the following query will scan all the data in the Heartbeat and Perf tables, not just the last 1 day:

Heartbeat 
| summarize arg_min(TimeGenerated,*) by Computer
| union (
    Perf 
    | summarize arg_min(TimeGenerated,*) by Computer) 
| where TimeGenerated > ago(1d)
| summarize min(TimeGenerated) by Computer

このクエリは次のように修正する必要があります。This query should be fixed as follows:

let MinTime = ago(1d);
Heartbeat 
| where TimeGenerated > MinTime
| summarize arg_min(TimeGenerated,*) by Computer
| union (
    Perf 
    | where TimeGenerated > MinTime
    | summarize arg_min(TimeGenerated,*) by Computer) 
| summarize min(TimeGenerated) by Computer

期間の測定値に関する制限Time span measurement limitations

測定値は、指定された実際の時間よりも常に大きくなります。The measurement is always larger than the actual time specified. たとえば、クエリのフィルターが 7 日の場合、システムでは 7.5 日分または 8.1 日分がスキャンされる可能性があります。For example, if the filter on the query is 7 days, the system might scan 7.5 or 8.1 days. これは、システムがデータを可変サイズのチャンクにパーティション分割しているためです。This is because the system is partitioning the data into chunks in variable size. 関連するすべてのレコードがスキャンされるようにするために、パーティションに保存されるレコードが数時間さらには 1 日分以上であっても、パーティション全体がスキャンされます。To assure that all relevant records are scanned, it scans the entire partition that might cover several hours and even more than a day.

場合によっては、システムが正確な時間範囲の測定値を提供できないことがあります。There are several cases where the system cannot provide an accurate measurement of the time range. これはほとんどの場合、クエリの範囲が 1 日未満であるか、複数のワークスペース クエリに含まれている場合に発生します。This happens in most of the cases where the query's span less than a day or in multi-workspace queries.

重要

この指標は、直近のクラスターで処理されたデータのみを示します。This indicator presents only data processed in the immediate cluster. 複数リージョンのクエリでは、リージョンのうち 1 つだけが表示されます。In multi-region query, it would represent only one of the regions. マルチワークスペース クエリでは、一部のワークスペースが含まれない場合があります。In multi-workspace query, it might not include all workspaces.

処理されたデータの期間Age of processed data

Azure Data Explorer では、インメモリ、ローカルの SSD ディスク、さらに処理速度の遅い Azure BLOB という複数のストレージ層が使用されています。Azure Data Explorer uses several storage tiers: in-memory, local SSD disks and much slower Azure Blobs. データが新しいほど、待ち時間が短い、より高性能な層に格納される確率が高くなり、クエリ期間と CPU が低減されます。The newer the data, the higher is the chance that it is stored in a more performant tier with smaller latency, reducing the query duration and CPU. システムには、データ自体に加え、メタデータ用のキャッシュもあります。Other than the data itself, the system also has a cache for metadata. データが古くなるほど、メタデータがキャッシュ内に存在する確率が低くなります。The older the data, the less chance its metadata will be in cache.

14 日以上が経過しているデータを処理するクリエは、リソースを過度に消費するクエリと見なされます。Query that processes data than is more than 14 days old is considered a query that consumes excessive resources.

クエリによっては古いデータの使用が必要な場合がありますが、古いデータが誤って使用されるケースもあります。While some queries require usage of old data, there are cases where old data is used by mistake. これは、メタデータに時間範囲を指定せずにクエリを実行した際に、一部のテーブル参照に TimeGenerated 列に対するフィルターが含まれていない場合に発生します。This happens when queries are executed without providing time range in their meta-data and not all table references include filter on the TimeGenerated column. このような場合、システムによって、そのテーブルに格納されているすべてのデータがスキャンされます。In these cases, the system will scan all the data that is stored in that table. データ保有期間が長い場合は、データ保有期間と同じ長い時間範囲 (したがって古いデータ) が対象となることがあります。When the data retention is long, it can cover long time ranges and thus data that is as old as the data retention period.

たとえば、次のようなケースがあります。Such cases can be for example:

  • Log Analytics で、制限されないサブクエリを使用して時間範囲が設定していないNot setting the time range in Log Analytics with a sub-query that isn't limited. (上記の例を参照)。See example above.
  • 時間範囲の省略可能なパラメーターを指定せずに API を使用している。Using the API without the time range optional parameters.
  • Power BI コネクタなど、時間範囲を強制しないクライアントを使用している。Using a client that doesn't force a time range such as the Power BI connector.

前のセクションの例と注意事項は、このケースにも関連するため、確認してください。See examples and notes in the pervious section as they are also relevant in this case.

リージョンの数Number of regions

1 つのクエリがさまざまなリージョンにわたって実行される可能性がある状況がいくつか考えられます。There are several situations where a single query might be executed across different regions:

  • 明示的に一覧表示されている複数のワークスペースが異なるリージョンに存在する場合。When several workspaces are explicitly listed, and they are located in different regions.
  • リソースでスコープが指定されたクエリでデータを取得し、異なるリージョンに存在する複数のワークスペースにそのデータが格納される場合。When a resource-scoped query is fetching data and the data is stored in multiple workspaces that are located in different regions.

リージョンをまたがるクエリを実行するには、通常はクエリの最終結果よりはるかに大きい、バックエンドの中間データ チャンクをシステムでシリアル化して転送する必要があります。Cross-region query execution requires the system to serialize and transfer in the backend large chunks of intermediate data that are usually much larger than the query final results. また、最適化、ヒューリスティック、キャッシュの利用を行うためのシステムの機能も制限されます。It also limits the system's ability to perform optimizations, heuristics, and utilize caches. これらのリージョンすべてをスキャンする理由がない場合は、対象のリージョンが絞り込まれるようにスコープを調整する必要があります。If there is no real reason to scan all these regions, you should adjust the scope so it covers fewer regions. リソースのスコープが最小化されても、多くのリージョンが使用されている場合は、構成の誤りが原因で生じる可能性があります。If the resource scope is minimized but still many regions are used, it might happen due to misconfiguration. たとえば、監査ログと診断設定が異なるリージョンにある別々のワークスペースに送信されたり、診断設定の構成が複数存在したりします。For example, audit logs and diagnostic settings are sent to different workspaces in different regions or there are multiple diagnostic settings configurations.

リージョンが 3 つ以上にまたがるクリエは、リソースを過度に消費するクエリと見なされます。Query that spans more than 3 regions is considered a query that consumes excessive resources. リージョンが 6 つ以上にまたがるクリエはリソースを酷使するクエリと見なされ、調整されることがあります。Query that spans more than 6 regions is considered an abusive query and might be throttled.

重要

1 つのクエリが複数のリージョンにわたって実行された場合、CPU とデータの測定値が正確ではなくなり、いずれか 1 つのリージョンの測定値のみが表示されます。When a query is run across several regions, the CPU and data measurements will not be accurate and will represent the measurement only on one of the regions.

ワークスペースの数Number of workspaces

ワークスペースは、ログ データを分離して管理するために使用される論理コンテナーです。Workspaces are logical containers that are used to segregate and administer logs data. バックエンドで、選択したリージョン内の物理クラスターにおけるワークスペースの配置が最適化されます。The backend optimizes workspace placements on physical clusters within the selected region.

複数のワークスペースが使用されるのは、次の場合が考えられます。Usage of multiple workspaces can result from:

  • 複数のワークスペースが明示的に一覧表示されている場合。Where several workspaces are explicitly listed.
  • リソースでスコープが指定されたクエリでデータを取得し、複数のワークスペースにそのデータが格納される場合。When a resource-scoped query is fetching data and the data is stored in multiple workspaces.

リージョンおよびクラスターにまたがるクエリを実行するには、通常はクエリの最終結果よりはるかに大きい、バックエンドの中間データ チャンクをシステムでシリアル化して転送する必要があります。Cross-region and cross-cluster execution of queries requires the system to serialize and transfer in the backend large chunks of intermediate data that are usually much larger than the query final results. また、最適化、ヒューリスティック、キャッシュの利用を行うためのシステムの機能も制限されます。It also limits the system ability to perform optimizations, heuristics and utilizing caches.

ワークスペースが 5 つ以上にまたがるクリエは、リソースを過度に消費するクエリと見なされます。Query that spans more than 5 workspace is considered a query that consumes excessive resources. クエリが 100 を超えるワークスペースにまたがることはありません。Queries cannot span to to more than 100 workspaces.

重要

マルチワークスペースのシナリオでは、CPU とデータの測定値が正確ではなくなり、ごく一部のワークスペースに測定値のみが表示されます。In some multi-workspace scenarios, the CPU and data measurements will not be accurate and will represent the measurement only to few of the workspaces.

ParallelismParallelism

Azure Monitor ログでは、Azure Data Explorer の大規模なクラスターを使用してクエリを実行しますが、これらのクラスターの規模は変動し、数十個の計算ノードになる可能性もあります。Azure Monitor Logs is using large clusters of Azure Data Explorer to run queries, and these clusters vary in scale, potentially getting up to dozens of compute nodes. このシステムでは、ワークスペースの配置ロジックと容量に応じて、クラスターが自動的にスケーリングされます。The system automatically scales the clusters according to workspace placement logic and capacity.

クエリを効率的に実行するために、クエリは、その処理に必要なデータに基づいてパーティション分割され、計算ノードに分散されます。To efficiently execute a query, it is partitioned and distributed to compute nodes based on the data that is required for its processing. システムでこれを効率的に実行できない状況もあります。There are some situations where the system cannot do this efficiently. この結果、クエリの期間が長くなる可能性があります。This can lead to a long duration of the query.

並列処理を低減できるクエリ動作は次のとおりです。Query behaviors that can reduce parallelism include:

  • シリアル化関数やウィンドウ関数 (serialize 演算子next ()prev ()row 関数など) の使用。Use of serialization and window functions such as the serialize operator, next(), prev(), and the row functions. このようなケースのいくつかでは、時系列およびユーザー分析関数を使用できます。Time series and user analytics functions can be used in some of these cases. また、rangesortordertoptop-hittersgetschema 演算子がクエリの末尾以外で使用されている場合にも、非効率的なシリアル化が発生する可能性があります。Inefficient serialization may also happen if the following operators are used not at the end of the query: range, sort, order, top, top-hitters, getschema.
  • dcount () 集計関数を使用すると、システムでは個別の値の中央コピーが強制的に保持されます。Usage of dcount() aggregation function force the system to have central copy of the distinct values. データのスケールが大きい場合は、dcount 関数の省略可能なパラメーターを使用して精度を下げることを検討してください。When the scale of data is high, consider using the dcount function optional parameters to reduced accuracy.
  • 多くの場合、join 演算子を使用すると全体的な並列処理が低下します。In many cases, the join operator lowers overall parallelism. パフォーマンスに問題がある場合は、代替手段としてシャッフル結合を試してください。Examine shuffle join as an alternative when performance is problematic.
  • リソースのスコープが指定されたクエリで、非常に多くの Azure のロールの割り当てがある状況では、実行前の Kubernetes RBAC または Azure RBAC チェックに時間がかかることがあります。In resource-scope queries, the pre-execution Kubernetes RBAC or Azure RBAC checks may linger in situations where there is very large number of Azure role assignments. その結果、チェックにかかる時間が長くなり、並列処理が低下する可能性があります。This may lead to longer checks that would result in lower parallelism. たとえば、多数のリソースがあり、各リソースに、サブスクリプションやリソース グループのレベルではなくリソースレベルでロールの割り当てが多数存在するサブスクリプションに対してクエリが実行されます。For example, a query is executed on a subscription where there are thousands of resources and each resource has many role assignments in the resource level, not on the subscription or resource group.
  • クエリで小さなデータ チャンクを処理している場合、システムがクエリを多数の計算ノードに分散させないため、その並列処理は少なくなります。If a query is processing small chunks of data, its parallelism will be low as the system will not spread it across many compute nodes.

次のステップNext steps