当使用 cosmos db 作为简单的键/值存储时,我应该使用什么索引模式/策略?
来自 https://learn.microsoft.com/en-us/azure/cosmos-db/index-policy :
无:容器上禁用索引。当容器用作纯键值存储而不需要二级索引时,通常会使用这种方法。
这是因为即使将indexMode 设置为“none”,用作分区键的属性也会被索引吗?我希望需要打开索引,但仅指定分区键的路径作为唯一包含的路径。
如果重要的话,我计划使用 SQL API。
编辑:
这是我理解这一点所缺少的信息:
id
属性,否则 cosmos db 将分配一个属性。 https://learn.microsoft.com/en-us/azure/cosmos-db/account-databases-containers-items#properties-of-an-itemid
的新列中:https://learn.microsoft .com/en-us/azure/data-factory/copy-activity-overview#add-additional-columns-during-copyReadItemAsync
,或者更好的是 ReadItemStreamAsync
,因为它不会反序列化响应,以便在不使用查询的情况下获取项目。
https://learn.microsoft.com/en-us/dotnet/api/microsoft.azure.cosmos.container.readitemasync?view=azure-dotnet
https://learn.microsoft.com/en-us/dotnet/api/microsoft.azure.cosmos.container.readitemstreamasync?view=azure-dotnet当您将
indexingMode
设置为 "none"
时,有效检索文档的唯一方法是通过 id
(例如 ReadDocumentAsync()
或 read_item()
)。这类似于键/值存储,因为您不会对其他属性执行查询;您将通过某个已知的 id 专门查找文档,并返回整个文档。从成本角度来看,对于 1K 文档来说,这将是 ~1RU,就像使用索引集合进行点读取一样。
您仍然可以运行查询,但如果没有索引,您会看到异常高的 RU 成本。
您仍然可以像通常那样通过点读取指定分区键的值。
我对此做了一些实验,并创建了一个带有索引策略的集合
{
"indexingMode": "none",
"automatic": false
}
我在其中插入了 100,003 个以下形式的文档
string id, string partitionKey, string someValue.
id
为"id"
且partitionKey从"0"
到"50000"
(含)的文档共有50,001个。id
为"id2"
且partitionKey从"0"
到"50000"
(含)的文档共有50,001个。id
为 "id3"
,partitionKey 为 "0"
。我尝试了以下查询
--50001 matching documents
SELECT COUNT(1)
FROM c
WHERE c.id = 'id'
--One matching document
SELECT COUNT(1)
FROM c
WHERE c.id = 'id3'
--Two matching documents
SELECT COUNT(1)
FROM c
where c.partitionKey = '2'
上述所有查询执行统计数据并不相同,但几乎相同(根据查询排序)
RU | 分区键范围 ID | 检索到的文档数 | 检索到的文档大小(以字节为单位) | 输出文档数 | 输出文档大小(以字节为单位) | 索引命中文档数 | 索引查找时间(毫秒) | 文档加载时间(毫秒) | 查询引擎执行时间(毫秒) | 系统函数执行时间(ms) | 用户定义函数执行时间(ms) | 文档写入时间(ms) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
3,266.10 | 0 | 100003 | 29728669 | 1 | 82 | 0 | 0 | 190.74 | 23.40 | 0 | 0 | 0 |
3,114.31 | 0 | 100003 | 29728669 | 2 | 156 | 0 | 0 | 197.32 | 21.85 | 0 | 0 | 0 |
3,398.89 | 0 | 100003 | 29728669 | 2 | 156 | 0 | 0 | 199.26 | 23.84 | 0 | 0 | 0 |
尝试
--One matching document
SELECT COUNT(1)
FROM c
where c.partitionKey = '2' and c.id = 'id'
提供了
5.62 RUs
的请求费用和 的统计数据
统计 | 价值 |
---|---|
RU | 5.62 |
分区键范围 ID | 0 |
检索到的文档数 | 1 |
检索到的文档大小(以字节为单位) | 293 |
输出文档数 | 1 |
输出文档大小(以字节为单位) | 78 |
索引命中文档数 | 1 |
索引查找时间(毫秒) | 0 |
文档加载时间(毫秒) | 0.06 |
查询引擎执行时间(毫秒) | 0.01 |
系统函数执行时间(ms) | 0 |
用户定义函数执行时间(ms) | 0 |
文档写入时间(ms) | 0 |
所以看起来
id
或分区键本身都没有任何有用的索引。两者都需要提供。
如果我使用 SDK 并进行实际的点读取而不是仅在数据浏览器中使用查询,那么上面的
5.62
RU 成本可能会降低。