使用 Azure Cosmos DB Python SDK 获取 SQL 查询执行指标并分析查询性能
适用范围: NoSQL
本文介绍如何使用查询执行指标分析 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
此查询加载了 60,951 个文档,总共为 399,998,938 字节。 加载这么多的字节会导致开销或请求单位费用增大。 它还花费了较长时间来执行查询,花费在属性上的明确总时间为:
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'])
若要详细了解如何优化查询性能,请参阅优化查询性能一文。