Hibernate查询性能

时间:2012-02-22 08:28:37

标签: java hibernate

我的桌子看起来像这样;

@Table
public class Person {

  private String name;
  private String address;
  ...
  private String score;
}

在我的数据库中,我现在有很多名字,地址和分数的人。假设我从另一个系统中检索一个人员列表,其中一些人已经存在于数据库中,一些人是新的。

在我将它们保存在我的数据库中之前,我想检查它们是否已经存在(避免重复),如果我进入的人与我已经拥有的人相同但是得分不同,则可能会改变分数。

如果我想选择所有存在的人,那么最好的查询是什么? (例如,相同的名称和地址)。我的人员表可能包含大量人员,而我从其他系统进入的人员名单也很大(新的或更新的分数)。我需要一个关于性能的查询:-)。

我正在使用Java和Hibernate。任何人吗?

编辑:最终的sql可能看起来像

select * from Person where name='Paul' AND address='road1 
OR name='John' AND address='road2'
OR name='Stella' AND address='road3'

以及更多......上面的sql atleast解释了我想要的东西。

2 个答案:

答案 0 :(得分:0)

这样做的一种方法是外连接两个表并列出一侧不存在的所有人。像这样(TSQL):

SELECT left.* from db1.owner.persons left LEFT JOIN db2.owner.persons right ON left.name=right.name AND left.address=right.address WHERE right.id IS NULL 

然后,您可以使用ISession的CreateSQLQuery方法获取人员列表。

在C#中我们这样写

var list=session.CreateSQLQuery(queryString,"left",new []{typeof(Person)}).List();

但我不认为这与java有很大不同

如果你想获得这个查询的性能,可能需要在每个表上放一些索引(例如,通过名称和地址)

答案 1 :(得分:0)

如果我理解正确,你已经拥有了所有“外部”人。

我会创建一个Map<String, ExternalPerson>,其中包含按名称索引的所有外部人员。

然后我会要求此地图的keySet()获取从数据库中获取的人员列表。

然后我会执行以下查询:

select p from Person p where p.name in (:names)

您只需确保名称数量不超过数据库强加的限制(Oracle中为1000)。如果是这样,您必须将该集合拆分为多个子集,并对每个子集重复查询。

然后迭代查询结果。对于找到的每个人,使用地图或外部人员获取其相应的外部人员,并更新当前人员的分数。然后从地图中删除外部人员。

在流程结束时,地图包含数据库中不存在的外部人员,并且必须创建。

如果这组人真的很高兴,请确保使用query.scroll()而不是query.list()来迭代这些人,并定期刷新并清除会话,如this section of the reference manual中所述,避免记忆问题。