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至少解释了我想要的。
I have a table looking something like this;
@Table
public class Person {
private String name;
private String address;
...
private String score;
}
In my database I now have a lot of persons with names, addresses and scores. Lets say I retrieve a list of persons from another system, where some of the persons already exist in the database and some are new.
Before I persist them in my DB I want to check if they already exist (avoid duplicates), and maybe change the score if the person I get in is the same as the one I already have, but with a different score.
Whats the best query to write if I want to select all persons that exist? (eg. same name and address). My table of persons can contain a huge amount of persons and the list of persons I get in from the other system is also big (new or with updated scores). I need a query that is all about performance :-).
I am using Java and Hibernate. Anyone?
EDIT: The final sql will probably look something like
select * from Person where name='Paul' AND address='road1
OR name='John' AND address='road2'
OR name='Stella' AND address='road3'
and many many more.. The above sql atleast explains what I want.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
执行此操作的一种方法是外部联接两个表并列出一侧不存在的所有人员。像这样(TSQL):
然后您可以使用 ISession 的 CreateSQLQuery 方法来获取人员列表。
在 C# 中我们这样写,
但我认为这在 java 中没有太大不同
如果你想通过这个查询获得性能,可能有必要在每个表上放置一些索引(例如,在名称和地址上)
One way of doing this is to outer join both tables and list all the persons that don't exist on a side . like this (TSQL):
Then you can use CreateSQLQuery method of ISession to get the list of persons.
in C# we write it like this
but I don't think that's much different in java
If you want to gain performance over this query probably it's necessary to put some indexes on each table (over name and address for example)
如果我理解正确的话,你已经记住了所有“外部”人物。
我将创建一个
Map
,其中包含按名称索引的所有外部人员。然后,我会要求该地图的
keySet()
从数据库中获取人员列表。然后我将执行以下查询:
您只需确保名称数量不超过数据库施加的限制(Oracle 中为 1000)。如果是这样,您必须将集合分成几个子集,并对每个子集重复查询。
然后迭代查询结果。对于找到的每个人,利用地图获取其对应的外部人或外部人,并更新当前人的分数。然后从地图上删除外部人员。
在该过程结束时,地图包含数据库中不存在且必须创建的外部人员。
如果人员数量确实很高,请确保使用
query.scroll()
而不是query.list()
来迭代人员,并定期刷新和清除会话如参考的这一部分中所述手动,以避免内存问题。If I understand correctly, you already have all your "external" persons in memory.
I would create a
Map<String, ExternalPerson>
containing all your external persons indexed by name.I would then ask the
keySet()
of this map to get the list of persons to get from the database.I would then execute the following query:
You just has to make sure that the number of names isn't above the limit imposed by your database (1000 in Oracle). If so, you'll have to split the set into several subsets, and repeat the query for each subset.
Then iterate over the query results. For each person found, get its corresponding external person using the map or external persons, and update the score of the current person. Then remove the external person from the map.
At the end of the process, the map contains the external persons that don't exist in the database, and must be created.
If the set of persons is really hign, make sure to use
query.scroll()
rather thanquery.list()
to iterate through the persons, and regularly flush and clear the session as explained in this section of the reference manual, to avoid memory problems.