Azure Cosmos DB Python SDK를 사용하여 SQL 쿼리 실행 메트릭 가져오기 및 쿼리 성능 분석

이 문서에서는 쿼리 실행 메트릭을 사용하여 Azure Cosmos DB에서 SQL 쿼리 성능을 프로파일링하는 방법을 설명합니다. 여기에는 요청에 대한 모든 실제 파티션에서 집계되는 누적 메트릭과 각 실제 파티션에 대한 메트릭 목록 및 총 요청 요금이 포함됩니다. 해당 메트릭은 쿼리 성능 조정 문서에서 보다 자세히 알아볼 수 있습니다.

쿼리 메트릭 사용

쿼리 메트릭을 얻으려면 아래와 같이 쿼리 매개 변수에서 populate_query_metrics 플래그를 True로 설정해야 합니다. 디버깅 목적으로도 인덱스 메트릭을 사용하도록 설정하는 데 관심이 있을 수 있으며 populate_query_metrics 플래그를 True로 설정하여 사용하도록 설정할 수 있습니다.

results = container.query_items(
    query=queryText,
    enable_cross_partition_query=True,
    populate_index_metrics=True,
    populate_query_metrics=True
)

쿼리 실행 메트릭 가져오기

Python SDK에서 컨테이너 클라이언트에서 x-ms-documentdb-query-metrics 헤더 값을 읽고 쿼리 실행 메트릭을 가져올 수 있습니다. 다음 코드 조각은 쿼리 실행 메트릭을 읽는 방법을 보여 줍니다.

results = container.query_items(
    query=queryText,
    enable_cross_partition_query=True,
    populate_query_metrics=True
)

items = [item for item in results]
'''
Please note that the last_response_headers are available only after the first iteration of the results as the query execution starts only when result iteration begins
'''
print("Query Metrics: ",container.client_connection.last_response_headers['x-ms-documentdb-query-metrics'])

결과는 아래와 같이 쿼리 실행 관련 정보를 제공합니다.

totalExecutionTimeInMs=0.27;
queryCompileTimeInMs=0.04;
queryLogicalPlanBuildTimeInMs=0.00;
queryPhysicalPlanBuildTimeInMs=0.02;
queryOptimizationTimeInMs=0.00;
VMExecutionTimeInMs=0.02;
indexLookupTimeInMs=0.00;
instructionCount=17;
documentLoadTimeInMs=0.01;
systemFunctionExecuteTimeInMs=0.00;
userFunctionExecuteTimeInMs=0.00;
retrievedDocumentCount=3;
retrievedDocumentSize=1005;
outputDocumentCount=3;
outputDocumentSize=1056;
writeOutputTimeInMs=0.00;
indexUtilizationRatio=1.00

위의 결과는 쿼리의 효율성에 대한 인사이트를 제공할 수 있습니다. totalExecutionTimeInMs를 확인하여 쿼리가 실행되는 데 걸린 시간을 확인할 수 있습니다. indexUtilizationRatio는 쿼리가 인덱스를 얼마나 잘 활용하는지에 대한 인사이트를 제공할 수 있습니다. 메트릭을 자세히 이해하려면 쿼리 실행 메트릭 문서를 참조하세요.

쿼리 요청 요금 가져오기

x-ms-request-charge 값을 읽음으로써 소비된 총 요청 단위(RU)를 캡처할 수 있습니다. 요청 요금을 검색하기 위해 매개 변수를 명시적으로 설정할 필요가 없습니다. 다음 예제에서는 쿼리의 각 연속 작업에 대한 요청 요금을 가져오는 방법을 보여줍니다.

items = [item for item in results]
print("Request Units consumed: ",container.client_connection.last_response_headers['x-ms-request-charge'])

인덱스 사용률 가져오기

인덱스 사용률을 살펴보면 느린 쿼리를 디버그하는 데 도움이 될 수 있습니다. 좋은 인덱스 사용률 점수는 1에 가까워야 합니다. 인덱스를 사용할 수 없는 쿼리는 결과 집합을 반환하기 전에 컨테이너의 모든 문서를 전체 검사합니다.

다음은 검사 쿼리의 예입니다.

SELECT VALUE c.description 
FROM   c 
WHERE UPPER(c.description) = "BABYFOOD, DESSERT, FRUIT DESSERT, WITHOUT ASCORBIC ACID, JUNIOR"

해당 쿼리 필터는 인덱스에서 제공하지 않는 UPPER 시스템 함수를 사용합니다. 대규모 컬렉션에 대해 이 쿼리를 실행하면 첫번째 연속에 대한 다음의 쿼리 메트릭이 생성됩니다:

QueryMetrics

Retrieved Document Count                 :          60,951
Retrieved Document Size                  :     399,998,938 bytes
Output Document Count                    :               7
Output Document Size                     :             510 bytes
Index Utilization                        :            0.00 %
Total Query Execution Time               :        4,500.34 milliseconds
Query Preparation Time                   :             0.2 milliseconds
Index Lookup Time                        :            0.01 milliseconds
Document Load Time                       :        4,177.66 milliseconds
Runtime Execution Time                   :           407.9 milliseconds
Document Write Time                      :            0.01 milliseconds

쿼리 메트릭 출력에서 다음 값을 확인합니다:

Retrieved Document Count                 :          60,951
Retrieved Document Size                  :     399,998,938 bytes

이 쿼리는 총 399,998,938바이트의 60,951개 문서를 로드했습니다. 이렇듯 많은 양의 바이트를 로드하면 높은 비용 또는 요청 단위 요금이 발생합니다. 또한 총 시간 사용 속성에서 명확히 확인할 수 있듯 쿼리 실행에 더 오랜 시간이 걸립니다:

Total Query Execution Time               :        4,500.34 milliseconds

즉, 쿼리가 실행되는데 (단 하나의 연속에만) 4.5초 정도가 걸렸습니다.

이 예제 쿼리를 최적화하려면 필터에서 UPPER 사용을 피하십시오. 대신 문서를 만들거나 업데이트할 때 c.description 값을 모두 대문자로 입력합니다. 그러면 쿼리가 다음과 같이 됩니다:

SELECT VALUE c.description 
FROM   c 
WHERE c.description = "BABYFOOD, DESSERT, FRUIT DESSERT, WITHOUT ASCORBIC ACID, JUNIOR"

그러면 이제 이 쿼리를 인덱스에서 제공할 수 있습니다. 계산된 속성을 사용하여 시스템 함수의 결과나 그렇지 않으면 전체 스캔을 유발할 수 있는 복잡한 계산을 인덱싱할 수 있습니다.

잠재적 인덱스 권장 사항을 살펴보고 사용된 인덱스를 확인하려면 populate_index_metrics 매개 변수를 True로 설정해야 하며 컨테이너 클라이언트에서 x-ms-documentdb-index-utilization 헤더 값을 읽을 수 있습니다. 다음 코드 조각은 인덱스 사용률 메트릭을 읽는 방법을 보여 줍니다.

results = container.query_items(
    query=queryText,
    enable_cross_partition_query=True,
    populate_index_metrics = True
)
items = [item for item in results]
print("Index Utilization Info: ",container.client_connection.last_response_headers['x-ms-cosmos-index-utilization'])

쿼리 성능 조정에 대한 자세한 내용은 쿼리 성능 조정 문서를 참조하세요.

참조

다음 단계