执行existsByEmail
方法时出现此错误:Cannot execute this query as it might involve data filtering and thus may have unpredictable performance. If you want to execute this query despite the performance unpredictability, use ALLOW FILTERING
表格:
CREATE TABLE user(id UUID, email varchar, first_name varchar, last_name varchar, PRIMARY KEY (id, email));
Java Spring代码:
@Repository
public interface UserRepository extends CassandraRepository<User, UUID> {
boolean existsByEmail(String email);
}
@Table
@Data
public class User {
@PrimaryKeyColumn(type = PrimaryKeyType.PARTITIONED, ordinal = 0)
private UUID id;
@PrimaryKeyColumn(ordinal = 1)
private String email;
@Column("first_name")
private String firstName;
@Column("last_name")
private String lastName;
}
请告诉我原因和解决方法。非常感谢
3条答案
按热度按时间uyhoqukh1#
出现此错误是因为基础请求未使用分区键(id)。
在您的例子中,email是一个集群列(因为如果没有显式提供,它是默认的
PrimaryKeyColumn
)对于您提供的bean,唯一有效的查询是
"为什么"
根据分区关键字的值对数据进行分区,以便在单个节点上访问所需的所有数据。您可以将要一起检索的数据分组在一起。将列定义为“已分区”列后,它将成为所有查询中的必需列。
使用Apache Cassandra,数据建模策略是基于查询创建表。(如果您需要通过多个请求访问相同的数据,以复制多个表中的数据,这是性能的折衷。
ego6inou2#
为什么
因为电子邮件是主键的第二个(群集)部分。在Cassandra Store中搜索它的性能很差。这正是警告所说的。
它解决方案
如果性能不是您的应用程序的问题(比如少于百万的电子邮件),那么您可以尝试允许过滤。
否则考虑改变你的模型。我建议去掉id,把email作为唯一的主键(和分区的)。
tf7tbtn23#
Mar-Z给出了一个关于改变数据模型的很好的建议。
id
多久查询一次user表?这是你经常容易访问的吗?如果不是,像这样重新键入表会有所帮助:如果您确实有需要
id
的查询,最佳实践是构建一个新查询来支持新查询。如果您不介意保持所有数据同步,则可以完全复制该表。或者,您可以仅使用它来引用user
表的id
,从而有效地使该表成为“手动索引”,如下所示:编辑
如果我想搜索用户的名字,姓氏,地址?
首先,“搜索”和“查询”是有区别的。搜索是提供非常自由的关键词,并期望得到一个大的结果集;查询是提供精确的条件,并期望得到一个特定的、通常很小的结果集。
记住这一点,您将需要确保主键定义与查询条件匹配,并按重要性降序排列。对于本例,按名字查询并不是非常有价值,因为常见的名字不会导致任何特定的内容。支持名称查询的表如下所示:
基本上,为名称查询构建一个表需要先有
last_name
,然后是first_name
和id
以确保唯一性。