Cosmos DB:更快的搜索选项

Cosmos DB : Faster Search Options

我们拥有巨大的 cosmosDB 容器,其中包含数十亿行和近 300 列。数据以我们大部分时间查询的方式进行分区和建模。

例如: 用户 table 由 userId 分区,这就是下面查询工作正常的原因。

Select * from User where userId = "user01234"

但在某些情况下,我们需要对数据进行不同的查询,需要先排序再查询。

例如:使用用户post和post

的日期从用户Table获取数据
Select * from user where userPostId = "P01234" orderBy date limit 100

由于数据量大且数据未根据查询 2(用户 Post)进行分区,此查询需要花费大量时间。

我的问题是 - 当数据未相应分区时,我们如何才能使 query2 和其他类似查询更快。

Option 1: "Create separate collection which is partitioned as per Query2" - This will make query faster but for any new query we will end up creating a new collection, which is duplication of billions of records. [Costly Option]

Option 2: "Build elastic search on top of DB?" This is time consuming option and may be over killing for this slow query problem.

还有其他选项可以使用吗?告诉我你的想法。

提前致谢!

两种选择都很昂贵。关键是决定哪个更便宜,包括 运行ning cross-partition 查询。这将需要您计算每个选项的成本。

对于 cross-partition 查询,在响应中捕获 RU 费用 object 以便您了解它的成本。

对于更改提要,这会产生前期成本,因为您 运行 它会超过您现有的 collection,但该成本是否仍然很高取决于每个月插入或更新的数据量。计算填充第二个 collection 的成本需要一些工作。您可以先在执行插入时测量响应 object 中的 RU 电荷,然后乘以行数。计算您需要多少吞吐量将取决于您希望多快填充第二个 collection。它还取决于您使用多少计算和多少实例来读取数据并将数据写入第二个 collection。

一旦第二个 collection 被填充,Change Feed 将花费 2 RU/s 来轮询更改(顺便说一句,这是可配置的)和 1 RU/s 来阅读每个新项目。将数据插入第二个 collection 的成本是您之前测量时的成本。

如果第二个查询没有得到 运行 那么频繁并且您的数据变化不大,那么更改提要可以为您省钱。如果您 运行 经常查询并且您的数据也经常更改,更改 Feed 仍然可以为您省钱。

关于弹性搜索或 Azure 搜索,我通常发现这比保持 cross-partition 查询或更改提要更昂贵。特别是如果您这样做只是为了回答第二个查询。通常,当您需要真正的自由文本查询功能时,这是一个更好的选择。

您可能探索的第三个选项是使用 Azure Synapse Link,然后 运行 两个查询都使用 SQL 无服务器或 Spark。

一些其他观察结果。

除非您 运行 在这些查询中需要所有 300 个属性,否则您可能需要考虑将这些项目分解成单独的文档并存储为单独的行。特别是如果您有高度不对称的更新模式,其中只有少量属性经常更新。这将为您节省大量更新费用,因为您更新的项目越小,它就越便宜(也更快)。

我建议的另一件事是查看您的索引策略并排除每个 属性 未在查询的 where 子句中使用的内容,并包括使用的属性。这将对刀片的 RU 消耗产生巨大影响。还要查看您的日期 属性 的复合索引,因为这对使用 order by 的查询有显着影响。