cassandra - SELECT DISTINCT cql 忽略 WHERE 子句

标签 cassandra distinct cql

执行两个相同的请求,但 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/

相关文章:

cassandra - 了解 cassandra 的内部数据存储

Cassandra Order by 目前仅支持按照 PRIMARY KEY 中声明的顺序对列进行排序

cassandra - 查询所有列cassandra

java - 如何在 junit 测试中停止 cassandra 嵌入式服务器

用于从两个表中选择 ID 列和最新日期的 SQL 语法

mongodb - 如何计算 MongoDB 中的不同值?

Mysql:如何为排名列表选择最近 24 小时的前 10 名用户(并避免多个用户条目)

cassandra - 如何更改 CQL 版本?

sql - 根据 id 匹配时另一个表中的值更新表中的列

node.js - 比较 Node.js 中的两个 uuid