我有一个JPA选择你收到一个参数然后我们可以使用一些属性(用户名,电子邮件,标识符)搜索用户只有一个文本字段来写标准文本。
问题是性能,在数据库中我们有大约9百万用户注册,搜索速度太慢,使用JPA,
形式: - 值(输入文本)
用户在表单中发送值(他没有说明他是否使用用户名,电子邮件或标识符)
用户(表)字段: - 标识符 - 名称 - 电子邮件
JPA查询:
select u from UserEntity u where u.alias LIKE lower(:query) OR u.email LIKE lower(:query) OR lower(u.identifier) LIKE lower(:query) ORDER BY u.alias
我不知道提高搜索速度的最佳方法是什么(我们在这些字段的表中有一些索引),如果我们删除u.identifier字段中的较低者,速度会提高很多(几乎是即时的)。但是我们可以通过很多方式获得标识符(迁移,寄存器,手动客户端插入......)
答案 0 :(得分:1)
我们注册了大约9百万用户,使用JPA搜索速度太慢
请注意,由于SQL查询本身太慢,无论执行查询所涉及的技术如何,搜索都会太慢。据说问题不是JPA,而是如何改进SQL查询。
将LOWER()函数与LIKE运算符组合会增加大量开销,因为在分析LIKE匹配之前,RDBMS必须将文本函数应用于3个字段。
恕我直言,一个好方法是使用VIEW来利用3个字段上的LOWER()部分,然后在此视图上执行查询(使用JPA进行BTW映射就像映射表一样简单):
CRAETE VIEW user_view AS SELECT id, lower(identifier) AS identifier, lower(alias) AS alias, lower(email) AS email FROM user;
然后创建一个搜索实体:
@Entity
@Table("user_view")
public class UserView {
@Basic private Long id;
@Basic private String identifier;
@Basic private String alias;
@Basic private String email;
// getters and setters as required
}
最后是JPQL查询:
String jqpl = "SELECT u FROM UserView u WHERE u.alias LIKE :query OR u.email LIKE :query OR u.identifier LIKE :query";
请注意,您可以直接以小写形式传递query
参数作为Query参数,您可以在查询执行后对结果列表进行排序。两者都将导致RDBMS减少工作量并因此改善总体响应时间。
答案 1 :(得分:0)
您可以使用不同的技术解决它。
一个是使用忽略大小写的整理。例如,在MySQL https://dev.mysql.com/doc/refman/5.7/en/case-sensitivity.html
中另一种策略是使用索引来派生字段。例如,在DB2中,您可以创建一个字段'lower_identifier始终生成为lower(identifier)'和字段中的索引,并且在执行较低搜索时会自动使用它。您不必在JPA中映射该字段。