我在cassandra中有一个表,其中A(String)和B(int)一起是分区键 我在Spark SQL中编写SQL查询
select ("SELECT * from table where A IN ("221",...) and B IN(32,323...));
在Explain计划中,它似乎是在进行批量扫描,而不是直接对分区键进行连接
== Physical Plan ==
Project [A,B ... other columns]
+- BatchScan[A,B ... other columns] Cassandra Scan: dev.table
也在文档https://github.com/datastax/spark-cassandra-connector/blob/master/doc/reference.md中 spark.cassandra.sql.inClauseToJoinConversionThreshold设置为25 ..
我很好奇,是否会出现主键上的In子句比直接联接更好的情况
答案 0 :(得分:2)
这对我有用
cqlsh> CREATE TABLE IF NOT EXISTS test.tab4 (k1 varchar, k2 int, PRIMARY KEY (k1, k2));
bin/spark-shell --packages com.datastax.spark:spark-cassandra-connector_2.12:3.0.0-beta --conf spark.cassandra.sql.inClauseToJoinConversionThreshold=10
scala> spark.conf.set(s"spark.sql.catalog.mycatalog", "com.datastax.spark.connector.datasource.CassandraCatalog")
scala> spark.sql("""SELECT * FROM mycatalog.test.tab4 where k1 in ("1","2","3","4") and k2 in (3,4,5,6,7)""").explain
== Physical Plan ==
*(1) Project [k1#43, k2#44]
+- BatchScan[k1#43, k2#44] class com.datastax.spark.connector.datasource.CassandraInJoin
如果谓词中使用的类型与C *模式不匹配,则转换可能无法进行。另外,请注意,inClauseToJoinConversionThreshold基于IN值的叉积。我的查询中的叉积为20。
仅对于较小的IN值叉积,In子句查询可能比直接联接更有效。默认值(2500)太高了,将来可能会降低。
如果这没有帮助,那么我将需要查看您的模式,发出的确切查询以及SCC / Spark版本。
答案 1 :(得分:0)
已经有一段时间没有完成Cassandra和Spark了,但是考虑到Cassandra中的键空间结构并没有那么令人困惑。 Cassandra通过哈希分区键将行分配到正确的分片。因此,如果查询很多不同的分区,则批量扫描可能会更快。我猜如果将其他模式用于表并将分区键移至列键,您将获得更理想的结果和更好的性能,因此您只需要对数据库本身使用过滤或范围操作即可。将所有结果映射到一起,就可以得到结果。