다음을 통해 공유


Kusto 쿼리 언어 쿼리에 대한 모범 사례

적용 대상: ✅Microsoft Fabric✅Azure Data ExplorerAzure MonitorMicrosoft Sentinel

쿼리를 더 빠르게 실행하기 위해 따라야 할 몇 가지 모범 사례는 다음과 같습니다.

간단히 말해서

작업 사용할 용어 사용하지 않음 주의
쿼리되는 데이터 양 줄이기 연산자 같은 메커니즘을 where 사용하여 처리되는 데이터의 양을 줄입니다. 처리되는 데이터의 양을 줄이는 효율적인 방법에 대한 자세한 내용은 처리되는 데이터 양 줄이기를 참조하세요.
중복 정규화된 참조 사용 방지 로컬 엔터티를 참조할 때 정규화되지 않은 이름을 사용합니다. 자세한 내용은 중복 정규화된 참조 사용 안 을 참조 하세요.
datetime 데이터 형식을 datetime 사용합니다. 데이터 형식을 long 사용하지 마세요. 쿼리에서는 Unix 시간 변환 함수(예: unixtime_milliseconds_todatetime().)를 사용하지 마세요. 대신 업데이트 정책을 사용하여 수집 중에 Unix 시간을 데이터 형식으로 datetime 변환합니다.
문자열 연산자 has 연산자를 사용합니다. contains은(는) 사용하지 마세요. 전체 토큰을 찾을 때 has는 부분 문자열을 찾지 않으므로 더 잘 작동합니다.
대/소문자 구분 연산자 ==을 사용합니다. =~를 사용하지 마십시오. 가능하면 대/소문자를 구분하는 연산자를 사용합니다.
in을 사용합니다. in~를 사용하지 마십시오.
contains_cs을 사용합니다. contains를 사용하지 마십시오. 사용 has/has_cs 은 .을 사용하는 것이 contains/contains_cs좋습니다.
텍스트 검색 특정 열을 찾습니다. *를 사용하지 마십시오. * 는 모든 열에서 전체 텍스트 검색을 수행합니다.
수백만 개의 행에서 동적 개체에서 필드 추출 대부분의 쿼리가 수백만 개의 행에 걸쳐 동적 개체에서 필드를 추출하는 경우 수집 시간에 열을 구체화합니다. 이 방법을 사용하면 열 추출에 대해 한 번만 지불합니다.
동적 개체에서 희귀 키/값 조회 MyTable | where DynamicColumn has "Rare value" | where DynamicColumn.SomeKey == "Rare value"을 사용합니다. MyTable | where DynamicColumn.SomeKey == "Rare value"를 사용하지 마십시오. 이 메서드를 사용하면 대부분의 레코드를 필터링하고 나머지에 대한 JSON 구문 분석만 수행합니다.
let 두 번 이상 사용하는 값이 있는 문 materialize() 함수사용합니다. materialize()를 사용하는 방법에 대한 자세한 내용은 materialize()를 참조하세요. 자세한 내용은 명명된 식을 사용하는 쿼리 최적화를 참조 하세요.
10억 개 이상의 레코드에 형식 변환 적용 쿼리를 변형하여 변환에 공급되는 데이터의 양을 줄입니다. 피할 수 있는 경우에는 많은 양의 데이터를 변환하지 마세요.
새 쿼리 마지막에 limit [small number] 또는 count를 사용합니다. 알 수 없는 데이터 세트에 대해 언바운드 쿼리를 실행하면 기가바이트 단위의 결과가 반환되어 응답 속도가 느리고 사용량이 많은 환경이 생성될 수 있습니다.
대/소문자를 구분하지 않는 비교 Col =~ "lowercasestring"을 사용합니다. tolower(Col) == "lowercasestring"를 사용하지 마십시오.
이미 소문자(또는 대문자)에 있는 데이터 비교 Col == "lowercasestring"(또는 Col == "UPPERCASESTRING"). 대/소문자를 구분하지 않는 비교를 사용하지 않습니다.
열 필터링 테이블 열에 대해 필터링합니다. 계산 열을 필터링하지 마세요.
T | where predicate(*Expression*) 사용 T | extend _value = *Expression* | where predicate(_value)은(는) 사용하지 마세요.
summarize 연산자 연산자의 카디널리티가 높은 경우 group by keys hint.shufflekey=<key>summarize 사용합니다. 높은 카디널리티는 이상적으로 100만 개 이상입니다.
join 연산자 행이 가장 적은 테이블을 첫 번째 행(쿼리에서 가장 왼쪽)으로 선택합니다.
단일 열로 필터링하는 데 왼쪽 세미 join 대신 사용합니다in.
클러스터 간 조인 대부분의 데이터가 있는 클러스터 또는 Eventhouse와 같은 원격 환경에서 조인의 "오른쪽" 쪽에서 쿼리를 실행합니다.
왼쪽이 작고 오른쪽이 큰 경우 조인 hint.strategy=broadcast를 사용합니다. 작은 값은 최대 100MB(메가바이트)의 데이터를 나타냅니다.
오른쪽이 작고 왼쪽이 큰 경우 조인 연산자 대신 조회 연산join 사용 조회의 오른쪽이 수십MB보다 크면 쿼리가 실패합니다.
양쪽이 너무 큰 경우 조인 hint.shufflekey=<key>를 사용합니다. 조인 키의 카디널리티가 높은 경우에 사용합니다.
동일한 형식 또는 패턴을 공유하는 문자열이 있는 열의 값 추출 구문 분석 연산자를 사용합니다. 여러 extract() 문을 사용하지 마세요. 예를 들어 값은 다음과 같습니다 "Time = <time>, ResourceId = <resourceId>, Duration = <duration>, ....".
extract() 함수 구문 분석된 문자열이 모두 동일한 형식이나 패턴을 따르지 않는 경우에 사용합니다. REGEX를 사용하여 필요한 값을 추출합니다.
materialize() 함수 구체화된 데이터 세트를 줄이고 쿼리의 의미 체계를 유지하는 가능한 모든 연산자를 푸시합니다. 예를 들어 필터 또는 프로젝트에 필요한 열만 있습니다. 자세한 내용은 명명된 식을 사용하는 쿼리 최적화를 참조 하세요.
구체화된 뷰 사용 일반적으로 사용되는 집계를 저장하기 위해 구체화된 뷰를 사용합니다. 함수를 materialized_view() 사용하여 구체화된 부분만 쿼리하는 것이 좋습니다. materialized_view('MV')

처리 중인 데이터 양 줄이기

쿼리의 성능은 처리해야 하는 데이터의 양에 따라 직접 달라집니다. 처리되는 데이터가 적을수록 쿼리가 빨라지고 소비하는 리소스가 줄어듭니다. 따라서 가장 중요한 모범 사례는 처리되는 데이터의 양을 줄이는 방식으로 쿼리를 구성하는 것입니다.

참고 항목

다음 토론에서는 필터 선택성의 개념을 염두에 두어야 합니다. 선택성은 일부 조건자를 필터링할 때 필터링되는 레코드의 백분율입니다. 고도로 선택적 조건자는 조건자를 적용한 후 소수의 레코드만 남아 있으므로 효과적으로 처리해야 하는 데이터의 양을 줄입니다.

중요도 순서:

  • 쿼리에 데이터가 필요한 참조 테이블만 있습니다. 예를 들어 와일드카드 테이블 참조가 있는 연산자를 사용하는 union 경우 와일드카드(*)를 사용하여 모든 테이블을 참조한 다음 원본 테이블 이름에 조건자를 사용하여 데이터를 필터링하는 대신 성능 관점에서 소수의 테이블만 참조하는 것이 좋습니다.

  • 쿼리가 특정 범위와만 관련된 경우 테이블의 데이터 범위를 활용합니다. table() 함수캐싱 정책(DataScope 매개 변수)에 따라 데이터를 범위 지정하여 데이터를 제거하는 효율적인 방법을 제공합니다.

  • where 테이블 참조 바로 다음에 쿼리 연산자를 적용합니다.

  • 쿼리 연산자를 where 사용하는 경우 단일 where 연산자 또는 여러 개의 연속 where 연산자를 사용하든 조건자를 배치하는 순서는 쿼리 성능에 상당한 영향을 미칠 수 있습니다.

  • 먼저 전체 분할 조건자를 적용합니다. 즉, extent_id() 함수 및 extent_tags() 함수를 사용하는 조건자를 먼저 적용해야 합니다. 또한 데이터를 특정 파티션으로 좁히는 선택적 조건자가 있는 경우 먼저 적용해야 합니다.

  • 그런 다음 테이블 열에 datetime 적용되는 조건자를 적용합니다. Kusto는 이러한 열에 효율적인 인덱스를 포함하며, 이러한 분할된 데이터베이스에 액세스할 필요 없이 전체 데이터 분할된 데이터베이스를 완전히 제거하는 경우가 많습니다.

  • 그런 다음, 적용되는 string 조건자 및 dynamic 열, 특히 용어 수준에서 적용되는 조건자를 적용합니다. 선택성을 사용하여 조건자를 정렬합니다. 예를 들어 수백만 명의 사용자가 있을 때 사용자 ID를 검색하는 것은 매우 선택적이며 일반적으로 인덱스가 매우 효율적인 용어 검색을 포함합니다.

  • 그런 다음 선택적이며 숫자 열을 기반으로 하는 조건자를 적용합니다.

  • 마지막으로, 테이블 열의 데이터를 검색하는 쿼리(예: contains "@!@!"조건자가 없고 인덱싱의 이점을 얻지 못하는 조건자의 경우)의 경우 데이터가 적은 열을 검사하는 조건자가 먼저 정렬되도록 조건자를 정렬합니다. 이렇게 하면 큰 열의 압축을 풉니다.

중복 정규화된 참조 사용 방지

이름별로 테이블 및 구체화된 뷰와 같은 엔터티를 참조합니다.

예를 들어 테이블을 단순히(정규화되지 않은 이름) 또는 데이터베이스 한정자(예database("DB").T: 테이블이 데이터베이스에 있는 DB경우)를 사용하거나 정규화된 이름(예cluster("<serviceURL>").database("DB").T: )을 사용하여 참조할 수 있습니다. T T

예를 들어 테이블을 단순히(정규화되지 않은 이름) 또는 데이터베이스 한정자(예database("DB").T: 테이블이 데이터베이스에 있는 DB경우)를 사용하거나 정규화된 이름(예cluster("X.Y.kusto.windows.net").database("DB").T: )을 사용하여 참조할 수 있습니다. T T

다음과 같은 이유로 중복되는 경우 이름 자격을 사용하지 않는 것이 가장 좋습니다.

  1. 정규화되지 않은 이름은 범위 내 데이터베이스에 속하는 것으로 식별하기 쉽습니다(사용자 읽기 권한자의 경우).

  2. 범위 내 데이터베이스 엔터티 참조는 항상 빠르며 경우에 따라 다른 데이터베이스에 속하는 엔터티보다 훨씬 빠릅니다.

이러한 데이터베이스가 다른 클러스터에 있는 경우 특히 그렇습니다.

이러한 데이터베이스가 다른 Eventhouse에 있는 경우 특히 그렇습니다.

정규화된 이름을 피하면 독자가 옳은 일을 할 수 있습니다.

참고 항목

그렇다고 해서 정규화된 이름이 성능에 좋지 않다는 의미는 아닙니다. 실제로 Kusto는 대부분의 경우 정규화된 이름이 데이터베이스 범위 내의 엔터티를 참조하는 경우를 식별하고 쿼리를 "단락"하여 클러스터 간 쿼리로 간주되지 않도록 할 수 있습니다. 그러나 필요하지 않은 경우 이를 사용하지 않는 것이 좋습니다.

참고 항목

그렇다고 해서 정규화된 이름이 성능에 좋지 않다는 의미는 아닙니다. 실제로 Kusto는 대부분의 경우 정규화된 이름이 데이터베이스 범위 내의 엔터티를 참조하는 경우를 식별할 수 있습니다. 그러나 필요하지 않은 경우 이를 사용하지 않는 것이 좋습니다.