azure 在遍历数组cosmos db之前对分区键进行筛选

rqqzpn5f  于 2023-02-05  发布在  其他
关注(0)|答案(2)|浏览(117)

我有一个CosmosDbQuery,工作正常,但有点慢和昂贵:

SELECT c.actionType as actionType, count(1) as count 
FROM c in t.processList
WHERE c.processTimestamp > @from
GROUP BY c.actionType

为了优化我的查询,我希望在遍历进程列表之前,首先在我的父partitionKey上有一个Where子句,例如parent.minute〉x。在这之后,就不需要c.processTimestamp〉@from了。

"id": "b6fd10cc-3a0b-4666-bf55-f22436a5f8d9",
"Name": "xxx",
"Age": 1,
"minute": 202302021026,
"processList": [
   {
      "processTimestamp": "2023-02-01T10:28:48.3004825Z",
      "actionType": "Action1",
      "oldValue": "2/1/2023 10:28:41 AM",
      "newValue": "2/1/2023 10:28:48 AM"
   },
   {
      "processTimestamp": "2023-02-01T10:28:48.3004825Z",
      "actionType": "Action2",
      "oldValue": "2/1/2023 10:28:48 AM",
      "newValue": "2/1/2023 10:28:48 AM"
   }],
}

我试过子查询和连接,但我不能让它工作:

SELECT c.actionType as actionType, count(1) as count 
FROM (SELECT * FROM C WHERE c.minute > 9) in t.processList
WHERE c.processTimestamp > @from
GROUP BY c.actionType")

我期望的结果是:

[
    {
        "actionType": "action1",
        "count": 85351
    },
    {
        "actionType": "action2",
        "count": 2354
    }
]
gfttwv5a

gfttwv5a1#

这里有一些评论。
正如我在评论中提到的,Group By与Sub-Queries是不受支持的,在这里进行了说明。
使用Date/Time值作为分区键通常是Cosmos DB的反模式。此查询可能速度慢且开销大,因为在大规模情况下,使用time作为分区键意味着大多数查询由于数据的新近性(较新的数据比较旧的数据获得更多请求)而命中同一分区。出于相同的原因,这对写入也不利。
当发生这种情况时,通常需要增加吞吐量。但是,这通常没有什么帮助,在某些情况下甚至会使情况变得更糟。此外,由于吞吐量在所有分区上均匀分布,这会导致较早日期的分区键上浪费未使用的吞吐量。
需要考虑两件事。让你的分区键结合两个属性来增加基数。在IOT场景中,这通常是deviceId_dateTimeHierarchical Partition keys,在预览版中,是你现在可以做的更好的方法)。这将有助于写操作,特别是在数据总是用当前日期时间写的情况下。
在查询的读取路径上,您可能会尝试使用更改馈送将实体化视图实施到第二个容器中。这将使读取吞吐量从用于接收的容器中移出,从而提高吞吐量的使用效率。但是,您应该自己测量吞吐量以确保这一点。
如果您的容器很小,并且将一直保持这种状态,那么下面的信息将不适用(〈10 K RU/s和50 GB)。

gywdnpxw

gywdnpxw2#

就像马克说的:子查询不支持Groupby。尝试使用linq修复它,但linq也不支持groupby,因此我更改了代码,使其使用join而不是使用IN关键字循环数组:

SELECT pl.actionType as actionType, count(1) as count 
FROM c 
JOIN pl IN c.processList 
WHERE c.minute > @from
GROUP BY pl.actionType")

相关问题