执行两个相同的请求,但 DISTINCT 关键字给出了意外的结果。如果没有关键字,结果还可以,但是如果使用 DISTINCT,则似乎忽略了 where 子句。为什么 ?
Cqlsh 版本:
Connected to Test Cluster at localhost:9160.
[cqlsh 4.1.1 | Cassandra 2.0.6 | CQL spec 3.1.1 | Thrift protocol 19.39.0]
考虑的表:
DESCRIBE TABLE events;
CREATE TABLE events (
userid uuid,
"timestamp" timestamp,
event_type text,
data text,
PRIMARY KEY (userid, "timestamp", event_type)
) WITH
bloom_filter_fp_chance=0.010000 AND
caching='KEYS_ONLY' AND
comment='' AND
dclocal_read_repair_chance=0.000000 AND
gc_grace_seconds=864000 AND
index_interval=128 AND
read_repair_chance=0.100000 AND
replicate_on_write='true' AND
populate_io_cache_on_flush='false' AND
default_time_to_live=0 AND
speculative_retry='99.0PERCENTILE' AND
memtable_flush_period_in_ms=0 AND
compaction={'class': 'SizeTieredCompactionStrategy'} AND
compression={'sstable_compression': 'LZ4Compressor'};
表内容:
SELECT * FROM events;
userid | timestamp | event_type | data
--------------------------------------+--------------------------+------------+------
aaaaaaaa-be1c-44ab-a0e8-f25cf6064b0e | 1970-01-17 09:06:17+0100 | toto | null
4271a78f-be1c-44ab-a0e8-f25cf6064b0e | 1970-01-17 09:06:17+0100 | toto | null
4271a78f-be1c-44ab-a0e8-f25cf6064b0e | 1970-01-17 09:07:17+0100 | toto | null
4271a78f-be1c-44ab-a0e8-f25cf6064b0e | 1970-01-17 09:08:17+0100 | toto | null
4271a78f-be1c-44ab-a0e8-f25cf6064b0e | 1970-01-17 09:09:17+0100 | toto | null
4271a78f-be1c-44ab-a0e8-f25cf6064b0e | 1970-01-17 09:10:17+0100 | toto | null
(6 rows)
Request1:没有 DISTINCT 的请求
SELECT userid FROM events WHERE timestamp > '1970-01-17 09:07:17+0100' ALLOW FILTERING;
userid
--------------------------------------
4271a78f-be1c-44ab-a0e8-f25cf6064b0e
4271a78f-be1c-44ab-a0e8-f25cf6064b0e
4271a78f-be1c-44ab-a0e8-f25cf6064b0e
(3 rows)
Request2:与 DISTINCT 相同的请求
SELECT DISTINCT userid FROM events WHERE timestamp > '1970-01-17 09:07:17+0100' ALLOW FILTERING;
userid
--------------------------------------
aaaaaaaa-be1c-44ab-a0e8-f25cf6064b0e
4271a78f-be1c-44ab-a0e8-f25cf6064b0e
(2 rows)
编辑 1
这是一些背景。
这个表“事件”受到大量写入的影响,它每秒接收大约 1k 次插入,我有一个批处理脚本每 5 分钟检查一次这些事件。
这个批处理脚本有两个需求:
1- 获取在过去 5 分钟内处于事件状态的所有用户 ID(即过去 5 分钟内出现在事件中的每个用户 ID)
2- 获取与这些用户 ID 相关的所有事件(不仅是最后 5 分钟)
我曾经有两个不同的表来处理这个问题。第一个请求的一个表“activeusers”和第二个请求的“事件”表,就像我在这里描述的那样。我的问题是它需要我的服务器在接收到事件时写入两个不同的表。所以我只使用事件表尝试了这个。
最佳答案
发生这种情况是因为在 Cassandra CQL 中 DISTINCT
旨在仅返回表(列族)的分区(行)键...必须是唯一的。因此,WHERE
当与 DISTINCT
一起使用时,子句只能对分区键进行操作(在您的情况下,这不是非常有用)。如果你拿 DISTINCT
出去,WHERE
然后可用于评估每个分区键内的集群(列)键(尽管使用 ALLOW FILTERING
)。
我觉得有必要提一下 ALLOW FILTERING
不是你应该做的很多事情......而且绝对不在生产中。如果该查询是您需要经常运行的查询(在某个 userids
之后查询 timestamp
的事件),那么我建议按 event_type
对您的数据进行分区反而:
PRIMARY KEY (event_type, "timestamp", userid)
然后你就可以在没有
ALLOW FILTERING
的情况下运行这个查询.SELECT userid FROM events WHERE event_type='toto' AND timestamp > '1970-01-17 09:07:17+0100'
在不了解您的应用程序或用例的情况下,这可能对您有用也可能没有用。但将其视为示例,并表明可能有更好的方法构建模型以满足您的查询模式。退房 Patrick McFadin's article on timeseries data modeling有关如何为这个问题建模的更多想法。
关于cassandra - SELECT DISTINCT cql 忽略 WHERE 子句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26548788/