使用主键和辅助键约束查询 Cassandra

Query Cassandra with Both Primary Key and Secondary Key Constraints

我在 Cassandra 中有一个 table 定义为

CREATE TABLE foo ("A" text, "B" text, "C" text,
    "D" text, "E" text, "F" text,
    PRMIARY KEY ("A", "B"),
    INDEX ("C"))

我在这个 table 中插入了数十亿条记录。现在我想用 CQL

查询 table
SELECT * FROM foo WHERE "A"='abc' AND "B"='def' AND "C"='ghi'

我一直收到 1200 错误提示

ReadTimeout: code=1200 [Coordinator node timed out waiting for replica nodes' responses] message="Operation timed out - received only 0 responses." info={'received_responses': 0, 'required_responses': 1, 'consistency': 'ONE'}

经过谷歌搜索,我怀疑这个错误的原因是查询被定向到一些不包含任何数据的分区。

我的问题是

  1. 在指定主键和副键的情况下查询CQL是否有任何约束?
  2. 如果我在我的 CQL 中指定了分区键,这里 "A"='abc'(如果错误请纠正我),为什么 C* 仍然尝试其他显然不保存数据的分区?
  3. 有解决这个超时问题的提示吗?

谢谢!

注意:对于我的示例,我去掉了列名周围的双引号。除了在列名称(而不是值)中保留大小写之外,它实际上没有做任何其他事情,只是为了搞砸工作。

Is there any constraint querying CQL with both primary key and secondary key specified?

首先,我需要弄清楚您的 "primary key" 和 "secondary key" 到底是什么。如果您将 C 称为 "secondary key,",则可以 "yes",但有一些限制。如果您指的是 partition 键 (A) 和 cluster 键 (B),那么是的,您可以.

通过您的分区键和集群键(或者甚至只是您的分区键)进行查询:

aploetz@cqlsh:Whosebug2> SELECT * FROM foo WHERe A='abc' AND B='def';

 a   | b   | c   | d   | e   | f
-----+-----+-----+-----+-----+-----
 abc | def | ghi | jkl | mno | pqr

(1 rows)
aploetz@cqlsh:Whosebug2> SELECT * FROM foo WHERe A='abc';

 a   | b   | c   | d   | e   | f
-----+-----+-----+-----+-----+-----
 abc | ddd | ghi | jkl | mno | pqr
 abc | def | ghi | jkl | mno | pqr

(2 rows)

当我创建您的 table 和索引时,插入几行,然后 运行 您的查询:

aploetz@cqlsh:Whosebug2> SELECT * FROM foo WHERE A='abc' AND B='def' AND C='ghi';

 a   | b   | c   | d   | e   | f
-----+-----+-----+-----+-----+-----
 abc | def | ghi | jkl | mno | pqr

(1 rows)

有效。

If I specified the partition key in my CQL, here "A"='abc' (correct me if wrong), why C* still tries other partition that apparently does not hold the data?

我不认为这是问题所在。您 将其限制为单个分区,因此它应该只查询 abc 分区之外的数据。

I inserted billions of records into this table.

您所看到的是二级索引使用在 Cassandra 中被认为是 "anti-pattern" 的原因。二级索引的工作方式与它们在关系世界中的工作方式不同。它们只是不能很好地扩展到大型集群或数据集。

Any hints to solve this timeout problem?

是的。使用 C 重新创建 table 作为第二个集群键。 不要C上创建索引。

CREATE TABLE foo (A text, B text, C text, D text, E text, F text,
  PRMIARY KEY (A, B, C));

重新加载您的数据,然后这应该适合您:

aploetz@cqlsh:Whosebug2> SELECT * FROM foo WHERE A='abc' AND B='def' AND C='ghi';

它不仅应该工作,而且应该不会超时,而且应该很快。