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

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

요컨대

작업 기능 사용하지 마세요. 참고
쿼리되는 데이터 양 줄이기 연산자 같은 메커니즘을 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를 사용합니다. 알 수 없는 데이터 세트에 대해 언바운드 쿼리를 실행하면 클라이언트에 반환되는 결과 GB가 생성되어 응답 속도가 느리고 클러스터가 사용량이 많은 경우가 발생할 수 있습니다.
대/소문자를 구분하지 않는 비교 Col =~ "lowercasestring" 사용 tolower(Col) == "lowercasestring"은 사용하지 마세요.
이미 소문자(또는 대문자)로 되어 있는 데이터 비교 Col == "lowercasestring"(또는 Col == "UPPERCASESTRING") 대/소문자를 구분하지 않는 비교를 사용하지 마세요.
열 필터링 테이블 열에 대해 필터링합니다. 계산 열을 필터링하지 마세요.
T | where predicate(*Expression*) 사용 T | extend _value = *Expression* | where predicate(_value)는 사용하지 마세요.
summarize 연산자 summarize 연산자의 가 카디널리티가 group by keys 높은 경우 hint.shufflekey=<key>를 사용합니다. 높은 카디널리티는 이상적으로 100만 이상입니다.
join 연산자 첫 번째 행이 될 행 수가 적은 테이블을 선택합니다(쿼리에서 가장 왼쪽).
단일 열로 필터링하려면 왼쪽 세미 join 대신 를 사용합니다in.
클러스터 간 조인 클러스터에서 대부분의 데이터가 있는 조인의 "오른쪽"에서 쿼리를 실행합니다.
왼쪽이 작고 오른쪽이 클 때 조인 hint.strategy=broadcast 사용 Small은 최대 100MB의 데이터를 나타냅니다.
오른쪽이 작고 왼쪽이 크면 조인 연산자 대신 조회 연산join 사용 조회의 오른쪽이 수십MB보다 크면 쿼리가 실패합니다.
양쪽 모두 너무 클 때 조인 hint.shufflekey=<key> 사용 조인 키의 카디널리티가 높을 때 사용합니다.
동일한 형식 또는 패턴을 공유하는 문자열로 열에서 값 추출 parse 연산자 사용 여러 가지 extract() 문을 사용하지 마세요. 예: "Time = <time>, ResourceId = <resourceId>, Duration = <duration>, ...."과 같은 값
extract() 함수 구문 분석된 문자열이 모두 동일한 형식이나 패턴을 따르지 않을 때 사용합니다. REGEX를 사용하여 필요한 값을 추출합니다.
materialize() 함수 구체화된 데이터 세트를 줄이고 쿼리의 의미 체계를 유지하는 가능한 모든 연산자를 푸시합니다. 예를 들어 필터 또는 프로젝트만 필수 열입니다. 자세한 내용은 명명된 식을 사용하는 쿼리 최적화를 참조하세요.
구체화된 뷰 사용 일반적으로 사용되는 집계를 저장하기 위해 구체화된 뷰 를 사용합니다. 함수를 materialized_view() 사용하여 구체화된 부분만 쿼리하는 것이 좋습니다. materialized_view('MV')

처리 중인 데이터 양 줄이기

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

참고

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

중요도 순서:

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

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

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

  • 쿼리 연산자를 where 사용할 때 조건자 순서를 신중하게 사용하는 경우(단일 연산자에서 또는 여러 연속 연산자가 있는 경우) 아래에 설명된 대로 쿼리 성능에 상당한 영향을 미칠 수 있습니다.

  • 전체 분할 조건자를 먼저 적용합니다. 즉 , extent_id() 함수를 사용하는 조건자는 테이블의 데이터 파티션(정의된 경우)에 대해 매우 선택적인 extent_tags() 함수 를 사용하는 조건자와 같이 먼저 적용되어야 합니다.

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

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

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

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

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

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

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

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

  2. scope 데이터베이스 엔터티를 참조하는 것은 항상 빠르며 경우에 따라 다른 데이터베이스에 속하는 엔터티(특히 해당 데이터베이스가 다른 클러스터에 있는 경우)가 훨씬 빠릅니다. 정규화된 이름을 피하면 독자가 옳은 일을 하는 데 도움이 됩니다.

참고

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