我的表格定义为:
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);
目标是拥有一个宽行的时间序列存储,以便categoryid
和date
(开始的开始(构成我的分区密钥,并且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')
- 计数是在少于100k记录的特定分区上
- 我在表演者MacBook Pro上只有一个Cassandra节点
- 在实例中没有主动写入/读取;少于20个开发笔记本电脑的分区
这是可以理解的是,当卡桑德拉(Cassandra(中的'exterth-is-a-a-write'概念被忽略时,这是一个共同的陷阱,因此为什么会发生墓碑。
执行扫描,在分区内部或跨分区中,我们需要将墓碑保持在内存中,以便我们可以将它们返回到协调器中,该协调器将使用它们来确保其他副本也知道已删除的行。通过产生大量墓碑的工作负载,这可能会导致性能问题,甚至耗尽服务器堆。
感谢 @jimwartnick关于可能与墓碑相关的潜伏期的建议;这是由于我的插入物所产生的 NULL
字段所产生的大量墓碑而被估计的。我没想到这会引起墓碑,我也不希望墓碑在查询性能方面很重要。特别是COUNT
。
解决方案
- 当不存在时使用字段中的默认未设置值或在插入/更新中完全省略它们
- 意识到以下事实,如卡桑德拉墓碑的常见问题所述-Alla Babkina
一个常见的误解是,只有在客户向卡桑德拉删除语句时才出现墓碑。一些开发人员认为,选择一种依靠卡桑德拉完全没有墓碑的操作方式是安全的。实际上,除了发出删除声明外,还有其他许多造成墓碑的事物。插入零值,插入收集和使用TTL到期的数据是墓碑的常见来源。