在“锡拉数据库”中获取N行的最佳方法

u4vypkhs  于 2022-09-27  发布在  Cassandra
关注(0)|答案(2)|浏览(171)

我有一个用例,其中我使用“锡拉数据库”来限制用户在过去24小时内的行为。假设用户在过去24小时内只允许下3次订单。我正在使用“锡拉数据库”的ttl,并计算表中的记录数以实现此目的。我还使用https://github.com/spaolacci/murmur3获取分区键的哈希值。
然而,我想知道查询表的最有效方法是什么。因此,我有几个问题想更好地理解并比较这些行为(如果我的陈述有任何错误,请纠正我):
1.使用count()
count()将实现一个完全扫描查询,这意味着它可能会向表中查询更多必要的记录。
从订单中选择COUNT(1)WHERE hash_id=?与user_id=?;
1.使用limit
limit将仅限制返回给客户端的记录数。这意味着它仍将查询与其 predicate 匹配的所有记录,但只限制返回的记录。
从订单中选择user_id WHERE hash_id=?AND user_id=?极限?;
1.使用寻呼
我对此有点陌生,但如果我正确阅读了文档,它应该只查询up,直到它收到前N条记录,而不必查询整个表。因此,如果我将页面大小限制为要获取的记录数,并且只查询第一页,那么它会正常工作吗?它会有一个一致的结果吗?
文档:https://java-driver.docs.scylladb.com/stable/manual/core/paging/index.html
我的查询仍然使用limit,但使用驱动程序通过https://github.com/gocql/gocql实现了这一点
iter:=conn.Query(“SELECT user_id FROM orders WHERE hash_id=?AND user_id=?LIMIT?”,hashID,userID,3).PageSize(3).PageState(nil).Iter()
请让我知道我的分析是否正确,最好选择哪种方法

vnzz0bqm

vnzz0bqm1#

您的客户机应该始终使用分页,否则会给查询协调器带来压力,这可能会导致延迟和内存碎片。如果您使用“锡拉监控”堆栈(如果不使用,您应该使用!),请参阅CQL Optimization Jmeter 板,更具体地说,请参阅Paged Queries面板。
现在,谈谈你的问题。看起来你的例子对于你真正想要实现的目标来说有点简约,即便如此,如果不是这样,我们也必须考虑大规模的设置。也许有一个租户可以在一天内下3个订单,但另一个租客可以在一周内下100万个订单?
如果上述假设是正确的,并且有了您现有的选项,那么最好使用LIMIT进行分页。原因是因为您手头的描述存在一些特殊问题:

  • 首先,您希望在特定的时间范围内检索N条记录,但您的查询没有指定这样的时间范围
  • 第二,e1d1e或LIMIT将启动分区扫描,目前尚不清楚如何进行hash_id+user_id组合以确定一个时间范围内的记录数。

当然,可能我错了,但我想建议一些不同的方法,这些方法可能不适用于您和您的用例。

  • 考虑集群键的时间戳组件部分。这将允许您避免使用以下查询进行完整分区扫描:

从订单中选择某物WHERE hash_id=?AND user_id=?和ts>=?与ts<?;

  • 如果上述内容不适用,那么Counter Table也许可以满足您的需求?您可以在下订单后增加一个计数器,然后查询计数器表,如下所示:

从counter_table中选择counter WHERE hash_id=?AND user_id=?AND日期=?;
我希望这有帮助!

pdsfdshx

pdsfdshx2#

我想对Felipe已经写过的内容补充几点:
首先,您不需要自己散列分区键。您可以使用任何您想要的分区键,甚至是连续的数字,分区键不需要是随机的。“锡拉”将自行在内部散列分区键,以改进负载平衡。你不需要知道或关心ScyllaDB使用的是哪种散列算法,但有趣的是,它也是murrous3的一种变体(它与你使用的不同,是Cassandra开发人员最初选择的一种改进算法)。
其次,您应该知道(并决定是否关心),在面对并发操作时,您试图强制实施的限制并不是一个硬限制:假设给定的分区已经有两条记录,现在两个并发记录添加请求进来了。两者都可以检查是否只有两条记录,确定可以添加第三条记录,然后当两者都添加其记录时,最终得到四条记录。您需要决定,如果用户幸运的话,一天可以收到4个请求,这对您来说是否合适,或者这是一场灾难。请注意,从理论上讲,您甚至可以获得4条以上的记录——如果用户设法同时发送N个请求,那么他们可能会在数据库中获得2+N条记录(但在通常情况下,他们无法获得许多多余的记录)。如果您想让3成为一个限制,您可能需要更改您的解决方案-可能是基于LWT的解决方案,而不是使用TTL。
第三,我想指出,当您预先知道最多只能有3个结果(或者,如上所述,可能只有4个或其他类似的小数字)时,COUNT和LIMIT之间没有重要的性能差异。如果您假设SELECT只产生三个或更少的结果,并且它不可能是一千个结果,那么您只检索或计数这些结果并不重要,您应该只做您方便的事情。无论如何,我认为分页不是您需要的好解决方案。对于这样短的结果,您可以只使用默认页面大小,但无论如何都无法达到它,并且分页提示服务器您可能会在下一个页面上继续读取,并且它会缓存需要执行此操作的缓冲区,而在这种情况下,您知道在前三个结果之后将永远不会继续。因此,简而言之,这里不要使用任何特殊的分页设置-只使用默认的页面大小(即1MB),无论如何都无法达到。

相关问题