我在Cassandra中有一张表定义为
CREATE TABLE foo ("A" text, "B" text, "C" text,
"D" text, "E" text, "F" text,
PRMIARY KEY ("A", "B"),
INDEX ("C"))
我在这张表中插入了数十亿条记录。现在我想用CQL查询表
SELECT * FROM foo WHERE "A"='abc' AND "B"='def' AND "C"='ghi'
我一直收到1200错误说
ReadTimeout:code = 1200 [协调器节点超时等待副本 节点的响应]消息=“操作超时 - 仅接收0 回复。“info = {'received_responses':0,'required_responses':1, '一致性':'ONE'}
谷歌搜索后,我怀疑这个错误的原因是查询被定向到一些不包含任何数据的分区。
我的问题是
谢谢!
答案 0 :(得分:4)
注意:对于我的示例,我删除了列名称周围的双引号。除了保留列名称中的大小写(而不是值)之外,它实际上没有做任何其他事情,只是用于破坏作品。
是否有任何约束查询CQL,同时指定了主键和辅助键?
首先,我需要清理你的“主键”和“辅助键”究竟是什么。如果您将C
称为“辅助密钥”,则可以使用“是”,但有一些限制。如果您的意思是分区密钥(A
)和群集密钥(B
),那么您可以。
通过分区和群集密钥(甚至只是分区密钥)进行查询:
aploetz@cqlsh:stackoverflow2> 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:stackoverflow2> 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)
当我创建表和索引时,插入几行,然后运行查询:
aploetz@cqlsh:stackoverflow2> 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)
有效。
如果我在我的CQL中指定了分区键,这里“A”='abc'(如果错误则纠正我),为什么C *仍会尝试其他显然不保存数据的分区?
我不相信这是问题所在。您 将其限制为单个分区,因此它只应查询abc
分区之外的数据。
我在这张表中插入了数十亿条记录。
您所看到的是二次索引使用被认为是Cassandra中的“反模式”的原因。辅助索引的工作方式与它们在关系世界中的工作方式不同。它们只是不能很好地扩展到大型集群或数据集。
解决此超时问题的任何提示?
是。使用C
作为第二个群集密钥重新创建表。并且不在C
上创建索引。
CREATE TABLE foo (A text, B text, C text, D text, E text, F text,
PRMIARY KEY (A, B, C));
重新加载您的数据,然后这应该适合您:
aploetz@cqlsh:stackoverflow2> SELECT * FROM foo WHERE A='abc' AND B='def' AND C='ghi';
它不仅应该起作用,而且它不应该超时,它应该很快。