1

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

例如:用户表由 userId 分区,这就是为什么下面的查询可以正常工作。

Select * from User where userId = "user01234"

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

例如:使用 userpost 和发布日期从用户表中获取数据

Select * from user where userPostId = "P01234" orderBy date limit 100

由于数据的大小,此查询需要大量时间,并且数据未根据 query2(用户 Post)进行分区。

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

选项 1:“创建根据 Query2 分区的单独集合” - 这将使查询更快,但对于任何新查询,我们最终都会创建一个新集合,这是数十亿条记录的重复。[昂贵的选择]

选项 2:“在 DB 之上构建弹性搜索?” 这是一个耗时的选项,并且对于这个缓慢的查询问题可能会过度杀戮。

还有其他可以使用的选项吗?让我知道你的想法。

提前致谢!

4

1 回答 1

2

这两种选择都很昂贵。关键是决定哪个更便宜,包括运行跨分区查询。这将要求您将这些选项中的每一个都计算出来。

对于跨分区查询,请在响应对象中捕获 RU 费用,以便了解它的成本。

对于更改提要,当您在现有集合上运行它时,这将产生前期成本,但该成本是否仍然很高取决于每月插入或更新的数据量。计算填充第二个集合的成本将需要一些工作。您可以首先在执行插入时测量响应对象中的 RU Charge,然后乘以行数。计算您需要多少吞吐量将取决于您希望以多快的速度填充第二个集合。它也是您使用多少计算和多少实例来读取数据并将数据写入第二个集合的函数。

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

如果第二个查询没有那么频繁地运行并且您的数据没有发生太大变化,那么更改提要可以为您节省资金。如果您经常运行此查询并且您的数据也经常更改,那么更改提要仍然可以为您省钱。

关于 Elastic Search 或 Azure Search,我通常发现这可能比保留跨分区查询或更改提要更昂贵。特别是如果您这样做只是为了回答第二个查询。通常,当您需要真正的自由文本查询功能时,这是一个更好的选择。

您可能会探索的第三个选项是使用 Azure Synapse Link,然后使用 SQL Serverless 或 Spark 运行这两个查询。

其他一些观察。

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

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

于 2020-12-21T20:30:27.547 回答