java - 如何通过连接集合限制结果集

标签 java hibernate spring-boot jpa query-optimization

我有一个用例,用户可以输入文本,系统会搜索匹配的发票。输入的文本可以匹配发票上的多个字段,也可以匹配发票行上的多个字段。

用户只能根据角色访问所有发票的子集。但这可能是数千张发票的列表。

搜索是通过直接的类似搜索结合通配符来完成的。 (查询是用hql写的)

在显示结果时,我们希望将其限制为 50,以免根据用户搜索的内容选择/处理数千个条目。但是,按照我加入的方式,数据库无法强制执行此限制。

我们曾经有类似(伪代码)的东西

select * from tbl_invoice
join tbl_useraccess .... :userid //a few joins happen here to limit to invoices             
//where the user has access to
where number like :input
or name like :input
or id in (select id from InvoiceLine where reference like :input)
limit top 50

这具有非常糟糕的性能,因为搜索是在每个发票行上完成的,而不仅仅是您有权访问的发票行,但总是给出正确的 50 行。

我已将其更改为

select * from tbl_invoice invoice
join tbl_useraccess .... :userid 
join tbl_invoiceline line on invoice.id = line.invoice_id    
where number like :input
or name like :input
or line.reference like :input
limit top 50

性能好多了(之前的语句只会超时),但限制不起作用,因为一张发票可能有多行。

我们可以从数据库中检索所有结果,将其映射到 java 对象,并在 Java 中执行最多 50 个结果,但我担心如果用户检索数千万条记录,这可能会耗尽我们的内存。

总之,我正在寻找一种更好的方法来检索固定的结果列表,但也能够在链接的 1-n 实体中进行搜索

最佳答案

select * from InvoiceLine line where reference like :input
join tbl_invoice invoice on invoice.id = line.invoice_id  
join tbl_useraccess .... :userid 
where number like :input
or name like :input
or line.reference like :input
limit top 50

这会将您的发票行限制为 50 行。

关于java - 如何通过连接集合限制结果集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54344992/

相关文章:

java - 自定义 ArrayList 到 Spinner

c++ - 类似 Hibernate 的 C++ 框架

java - Eclipse 符合 "Unresolved generator name"但一切正常

java - keycloak-admin-client在springboot中总是返回null

java - 注入(inject) Google 和 Facebook 连接工厂

java - Spring JPA 存储库仅在结果已存在时获取 id 而不是完整对象

java - 在不同情况下执行可执行文件 (.exe) 的正确方法

java - 如何将结果与 Struts 2 中返回对象的操作的 return 语句相匹配?

java - 更改 Netbeans 平台主窗口背景颜色

重用部分查询进行计数的 Java 编码最佳实践