我们有单个Cassandra节点。
使用表格:
CREATE TABLE test (
pk bigint,
b text,
d int,
PRIMARY KEY ((pk))
);
CREATE INDEX test_d_idx ON test (d);
cqlsh
中的查询select * from test where d = 20140407
也快速工作。
但Spark的DataStax驱动程序生成查询:
SELECT "d", "b" FROM "test" WHERE token("pk") > 6755909504673608635 AND d = 20140407 ALLOW FILTERING
这很慢。
SELECT partitioner FROM system.local;
返回
> org.apache.cassandra.dht.Murmur3Partitioner
问题:如何以这种方式配置一个节点,SELECT with token(" pk")可以快速工作?
表包含10 ^ 7行(如果表包含1000行,显然可以快速工作)。
答案 0 :(得分:2)
SELECT "d", "b" FROM "test"
WHERE token("pk") > 6755909504673608635 AND d = 20140407 ALLOW FILTERING
哇,Spark生成了那个查询?这不起作用的原因是,当使用equals运算符指定WHERE
值时,PRIMARY KEY
子句中的二级索引上的查询仅与PRIMARY KEY
一起使用。基本上> 运算符没有给Cassandra足够的信息来知道值在哪个分区上,所以它必须全部搜索它们(这就是为什么需要这么长时间)。
我觉得这里有更好的选择,而不是test(d)
上的二级索引,创建一个额外的查询表(并修改你的应用程序以将数据保存到该表中):
CREATE TABLE testbyd (
d int,
pk bigint,
b text,
PRIMARY KEY (d,pk)
);
虽然我不能说Spark会如何处理该表,但我可以告诉你这个CQL查询将在该表上运行:
SELECT d, b
FROM testbyd
WHERE d=20140407 AND pk > 6755909504673608635;
同样,这个CQL查询:
select * from testbyd where d = 20140407;
...比“测试”表的表现要好得多。无论如何,请给出一个镜头,看看Spark如何处理该查询表。