【发布时间】:2020-12-31 22:34:30
【问题描述】:
微软明确表示跨分区查询将查询“扇出”到每个分区 (link):
以下查询对分区键 (DeviceId) 没有过滤器。因此,它必须扇出到针对每个分区的索引运行它的所有物理分区:
所以我很好奇是否可以通过对分区键(例如 STARTSWITH)进行范围查询来优化“扇出”。
为了测试它,我创建了一个包含七个文档的小型 Cosmos DB:
{
"partitionKey": "prefix1:",
"id": "item1a"
},
{
"partitionKey": "prefix1:",
"id": "item1b"
},
{
"partitionKey": "prefix1:",
"id": "item1c"
},
{
"partitionKey": "prefix1X:",
"id": "item1d"
},
{
"partitionKey": "prefix2:",
"id": "item2a"
},
{
"partitionKey": "prefix2:",
"id": "item2b"
},
{
"partitionKey": "prefix3:",
"id": "item3a"
}
它具有分区键“/partitionKey”的默认索引策略。然后我跑了一堆查询:
SELECT * FROM c WHERE STARTSWITH(c.partitionKey, 'prefix1')
-- Actual Request Charge: 2.92 RUs
SELECT * FROM c WHERE c.partitionKey = 'prefix1:' OR c.partitionKey = 'prefix1X:'
-- Actual Request Charge: 3.02 RUs
SELECT * FROM c WHERE STARTSWITH(c.partitionKey, 'prefix1:')
SELECT * FROM c WHERE c.partitionKey = 'prefix1:'
-- Each Query Has Actual Request Charge: 2.89 RUs
SELECT * FROM c WHERE STARTSWITH(c.partitionKey, 'prefix2')
SELECT * FROM c WHERE c.partitionKey = 'prefix2:'
-- Each Query Has Actual Request Charge: 2.86 RUs
SELECT * FROM c WHERE STARTSWITH(c.partitionKey, 'prefix3')
SELECT * FROM c WHERE c.partitionKey = 'prefix3:'
-- Each Query Has Actual Request Charge: 2.83 RUs
SELECT * FROM c WHERE c.partitionKey = 'prefix2:' OR c.partitionKey = 'prefix3:'
-- Actual Request Charge: 2.99 RUs
重新运行查询时,请求费用是一致的。并且费用增长的模式似乎与结果集和查询复杂性一致,可能是“OR”查询除外。但是,然后我尝试了这个:
SELECT * FROM c
-- Actual Request Charge: 2.35 RUs
所有分区的基本扇出甚至比针对特定分区更快,即使使用相等运算符也是如此。我不明白这是怎么回事。
话虽如此,我的示例数据库非常小,只有七个文档。查询集可能不够大,无法信任结果。
那么,如果我有数百万个文档,STARTSWITH(c.partitionKey, 'prefix') 会比散播到所有分区更优化吗?
【问题讨论】:
标签: azure-cosmosdb azure-cosmosdb-sqlapi