EnableScan InQuiry 不再适用于新的 Cosmos DB 容器
EnableScanInQuery no longer works for new CosmosDB containers
我对 cosmos-db 索引策略和隐式全扫描感到困惑。
我的最终目标是:
- 防止对非索引属性的意外全扫描
- 仅索引明确指定的属性
假设我有一个像这样的table:
{
"id": "transactions",
"indexingPolicy": {
"indexingMode": "consistent",
"automatic": true,
"includedPaths": [
{
"path": "/transactionId/?"
},
{
"path": "/createdOn/?"
}
],
"excludedPaths": [
{
"path": "/*"
},
{
"path": "/\"_etag\"/?"
}
]
},
"partitionKey": {
"paths": [
"/chargePointId"
],
"kind": "Hash"
}
}
我想这意味着我正好有 2 个一致的索引(在 transactionId 和 createdOn 列上)。 Azure 门户不允许我指定索引类型:它 "accepts" 更改,但是当它重新加载页面时所有更改都消失了。
现在我在一个不存在的列上执行查询并禁用全扫描,假设它会失败并出现错误:An invalid query has been specified with filters against path(s) excluded from indexing. Consider adding allow scan header in the request.
.
但是,这并没有发生。它工作正常并在控制台中打印 00:00:00
。
var policy = new ConnectionPolicy()
{
ConnectionMode = ConnectionMode.Gateway
};
var client = new DocumentClient(host, key, policy);
var queryText = "select * from c where c.asdasdasd > '2'";
var query = client.CreateDocumentQuery(
UriFactory.CreateDocumentCollectionUri("transactions", "transactions"),
queryText,
new FeedOptions
{
PopulateQueryMetrics = true,
EnableScanInQuery = false,
EnableCrossPartitionQuery = true,
}
).AsDocumentQuery();
var result = await query.ExecuteNextAsync();
var metrics = result.QueryMetrics;
Console.WriteLine(metrics.Single().Value.QueryEngineTimes.IndexLookupTime);
(代码取自本指南https://docs.microsoft.com/en-us/azure/cosmos-db/sql-api-query-metrics)
我说的table是最近(~几周前)创建的。我在很久以前创建的另一个数据库帐户中也有一个 table。如果我尝试对 table 使用相同的技巧 - 它会如我所料失败。
我没有发现帐户或 table arm-templates(从 azure 门户导出)有任何差异。
为什么它在新 table 上不失败?
它是否仍然默默地索引事物或 EnableScanInQuery
不再受新 table 的尊重?
我来自 CosmosDB 工程团队。我们正在逐步取消对 EnableScanInQuery 的支持,因为它并未对每个可能的查询统一强制执行(例如 SELECT * 来自 r)。此外,当 EnableScanInQuery 设置为 false 时仍然允许部分扫描(即使查询中选择性最少的谓词之一满足大量文档并且可以从索引提供服务,我们也会接受查询,即使它可以有效地扫描)。对于今年年初开始的新容器,支持将逐渐取消。优化查询以避免扫描的推荐方法是检查查询执行指标以确定是否需要针对索引策略进行任何优化。
这实际上意味着不管 EnableScanInQuery,查询可能会降级为自动扫描以提供结果,并且对于不支持此选项的容器,用户不会看到任何错误消息。
我对 cosmos-db 索引策略和隐式全扫描感到困惑。
我的最终目标是:
- 防止对非索引属性的意外全扫描
- 仅索引明确指定的属性
假设我有一个像这样的table:
{
"id": "transactions",
"indexingPolicy": {
"indexingMode": "consistent",
"automatic": true,
"includedPaths": [
{
"path": "/transactionId/?"
},
{
"path": "/createdOn/?"
}
],
"excludedPaths": [
{
"path": "/*"
},
{
"path": "/\"_etag\"/?"
}
]
},
"partitionKey": {
"paths": [
"/chargePointId"
],
"kind": "Hash"
}
}
我想这意味着我正好有 2 个一致的索引(在 transactionId 和 createdOn 列上)。 Azure 门户不允许我指定索引类型:它 "accepts" 更改,但是当它重新加载页面时所有更改都消失了。
现在我在一个不存在的列上执行查询并禁用全扫描,假设它会失败并出现错误:An invalid query has been specified with filters against path(s) excluded from indexing. Consider adding allow scan header in the request.
.
但是,这并没有发生。它工作正常并在控制台中打印 00:00:00
。
var policy = new ConnectionPolicy()
{
ConnectionMode = ConnectionMode.Gateway
};
var client = new DocumentClient(host, key, policy);
var queryText = "select * from c where c.asdasdasd > '2'";
var query = client.CreateDocumentQuery(
UriFactory.CreateDocumentCollectionUri("transactions", "transactions"),
queryText,
new FeedOptions
{
PopulateQueryMetrics = true,
EnableScanInQuery = false,
EnableCrossPartitionQuery = true,
}
).AsDocumentQuery();
var result = await query.ExecuteNextAsync();
var metrics = result.QueryMetrics;
Console.WriteLine(metrics.Single().Value.QueryEngineTimes.IndexLookupTime);
(代码取自本指南https://docs.microsoft.com/en-us/azure/cosmos-db/sql-api-query-metrics)
我说的table是最近(~几周前)创建的。我在很久以前创建的另一个数据库帐户中也有一个 table。如果我尝试对 table 使用相同的技巧 - 它会如我所料失败。
我没有发现帐户或 table arm-templates(从 azure 门户导出)有任何差异。
为什么它在新 table 上不失败?
它是否仍然默默地索引事物或 EnableScanInQuery
不再受新 table 的尊重?
我来自 CosmosDB 工程团队。我们正在逐步取消对 EnableScanInQuery 的支持,因为它并未对每个可能的查询统一强制执行(例如 SELECT * 来自 r)。此外,当 EnableScanInQuery 设置为 false 时仍然允许部分扫描(即使查询中选择性最少的谓词之一满足大量文档并且可以从索引提供服务,我们也会接受查询,即使它可以有效地扫描)。对于今年年初开始的新容器,支持将逐渐取消。优化查询以避免扫描的推荐方法是检查查询执行指标以确定是否需要针对索引策略进行任何优化。
这实际上意味着不管 EnableScanInQuery,查询可能会降级为自动扫描以提供结果,并且对于不支持此选项的容器,用户不会看到任何错误消息。