为什么在相对较小的数据集上,在特定分区上的Cassandra计数(*)需要很长时间



我的表格定义为:

Keyspace

CREATE KEYSPACE messages WITH replication = {'class': 'SimpleStrategy', 'replication_factor': '1'} AND durable_writes = true;

CREATE TABLE messages.textmessages (
    categoryid int,
    date timestamp,
    messageid timeuuid,
    message text,
    userid int,
    PRIMARY KEY ((categoryid, date), messageid)
) WITH CLUSTERING ORDER BY (messageid ASC);

目标是拥有一个宽行的时间序列存储,以便categoryiddate(开始的开始(构成我的分区密钥,并且messageid提供了聚类。这使我能够进行查询:

SELECT * FROM messages.textmessages WHERE categoryid=2 AND date='2019-05-14 00:00:00.000+0300' AND messageId > maxTimeuuid('2019-05-14 00:00:00.000+0300') AND messageId < minTimeuuid('2019-05-15 00:00:00.000+0300')

在给定的一天中获取消息;它运作得如此之快!

问题

我需要能够在给定的一天内通过用SELECT COUNT(*)替换SELECT *来计算消息。这需要很长时间,即使在专栏一家中有不到100k的条目。它实际上在cqlsh

我已经阅读并理解了很多内容,为什么COUNT是Cassandra(例如Cassandra(计数键的分布式数据库的昂贵操作?也可能在计算恒星

问题

为什么此查询即使是:

时也需要这么长时间
SELECT COUNT(*) FROM messages.textmessages WHERE categoryid=2 AND date='2019-05-14 00:00:00.000+0300' AND messageId > maxTimeuuid('2019-05-14 00:00:00.000+0300') AND messageId < minTimeuuid('2019-05-15 00:00:00.000+0300')
  1. 计数是在少于100k记录的特定分区上
  2. 我在表演者MacBook Pro上只有一个Cassandra节点
  3. 在实例中没有主动写入/读取;少于20个开发笔记本电脑的分区

这是可以理解的是,当卡桑德拉(Cassandra(中的'exterth-is-a-a-write'概念被忽略时,这是一个共同的陷阱,因此为什么会发生墓碑。

执行扫描,在分区内部或跨分区中,我们需要将墓碑保持在内存中,以便我们可以将它们返回到协调器中,该协调器将使用它们来确保其他副本也知道已删除的行。通过产生大量墓碑的工作负载,这可能会导致性能问题,甚至耗尽服务器堆。

感谢 @jimwartnick关于可能与墓碑相关的潜伏期的建议;这是由于我的插入物所产生的 NULL字段所产生的大量墓碑而被估计的。我没想到这会引起墓碑,我也不希望墓碑在查询性能方面很重要。特别是COUNT

解决方案

  1. 当不存在时使用字段中的默认未设置值或在插入/更新中完全省略它们
  2. 意识到以下事实,如卡桑德拉墓碑的常见问题所述-Alla Babkina

一个常见的误解是,只有在客户向卡桑德拉删除语句时才出现墓碑。一些开发人员认为,选择一种依靠卡桑德拉完全没有墓碑的操作方式是安全的。实际上,除了发出删除声明外,还有其他许多造成墓碑的事物。插入零值,插入收集和使用TTL到期的数据是墓碑的常见来源。

最新更新