我们有一个巨大的cosmosdb容器,有数十亿行和近300列。数据是以我们大部分时间查询的方式进行分区和建模的。
例如:用户表是按userid分区的,这就是为什么下面的查询可以正常工作的原因。
Select * from User where userId = "user01234"
但在某些情况下,我们需要以不同的方式查询需要排序然后查询的数据。
例如:使用userpost和post日期从用户表中获取数据
Select * from user where userPostId = "P01234" orderBy date limit 100
由于数据的大小和数据没有基于query2(user post)进行分区,因此此查询需要花费大量时间。
我的问题是-当数据没有相应分区时,我们如何使query2和其他类似的查询更快。
选项1:“创建单独的集合,并按照query2进行分区”-这将使查询速度更快,但对于任何新查询,我们最终将创建一个新集合,这是数十亿条记录的重复[昂贵的选择]
选项2:“在db上构建ElasticSearch?”这是一个耗时的选项,对于这个缓慢的查询问题来说,这可能太费劲了。
还有其他的选择吗?让我知道你的想法。
提前谢谢!
1条答案
按热度按时间jrcvhitl1#
两种选择都很昂贵。关键是决定哪个更便宜,包括运行跨分区查询。这将需要您计算出每个选项的成本。
对于跨分区查询,捕获response对象中的ru费用,以便知道它的成本。
对于changefeed,当您在现有集合上运行它时,这将有一个前期成本,但是这个成本是否仍然很高取决于每月插入或更新多少数据。计算填充第二个集合的成本需要一些工作。在执行插入操作时,可以首先测量响应对象中的ru电荷,然后乘以行数。计算您需要多少吞吐量将是您希望以多快的速度填充第二个集合的函数。它也是一个函数,用于计算多少计算量,以及使用多少示例将数据读写到第二个集合。
填充第二个集合后,change feed将花费2ru/s来轮询更改(顺便说一句,这是可配置的),花费1ru/s来读取每个新项。将数据插入第二个集合的成本与您之前测量数据时的成本是一样的。
如果第二个查询不经常运行,并且您的数据变化不大,那么changefeed可以为您节省资金。如果您经常运行此查询,并且您的数据也经常更改,那么change feed仍然可以为您节省资金。
关于ElasticSearch或azure搜索,我通常发现这可能比保留跨分区查询或更改提要更昂贵。尤其是你这样做只是为了回答第二个问题。通常,当您需要真正的自由文本查询功能时,这是一个更好的选择。
第三种方法是使用azuresynapse链接,然后使用sqlserverless或spark运行这两个查询。
其他一些观察。
除非在运行的这些查询中需要所有300个属性,否则您可能需要考虑将这些项分解为单独的文档并存储为单独的行。特别是如果您有高度不对称的更新模式,其中只有少量属性经常更新。这将为您节省大量的更新费用,因为您更新的项目越小,它就越便宜(和更快)。
我建议的另一件事是查看索引策略,排除查询的where子句中未使用的所有属性,并包括未使用的属性。这将对插入件的ru消耗产生巨大影响。还可以查看date属性的复合索引,因为这对使用orderby的查询有很大的影响。