이 문서에서는 쿼리 실행 메트릭을 사용하여 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'])
쿼리 성능 조정에 대한 자세한 내용은 쿼리 성능 조정 문서를 참조하세요.