我相信我可以提高休眠以下findByName查询的性能:什么是最快速的findByName查询与休眠?
public List<User> findByName(String name) {
session.createCriteria(User.class).add(Restrictions.eq("name", name)).list();
}
瓶颈是findByName方法,我不能使用id来代替。
在我的情况下,我知道该名称是唯一的,但将名称注释添加到name属性并没有提高性能。我做了以下内容:
class User {
@Index(name = "nameIdx")
private String name;
}
在哪种方式,我应该改进它,甚至更重要的是:在这方面,我应该首先改善了吗?我将需要这个类的所有集合(无论是否是)和全部的全部对象。
或者我可以改进它,如果我想要几个用户对象(并知道几个名字)?
UPDATE1:
的@index注释没有提高性能,因为数据库已经有了一个指标,因为我的唯一约束注释:
@UniqueConstraint(columnNames = {"name"})
UPDATE2:
请仔细阅读答案!
在SQL日志的帮助下,我发现真正的问题是很多更新和插入语句被引发,尽管我没有提交或刷新事务。 背后的原因是,我做了(在一个循环中):
User u = findByName(name); if(u == null) attach(u = new User(name));
等Hibernate需要每findByName查询之前刷新新创建的用户数据库。我用我自己的缓存解决方法(LinkedHashMap)解决了这个问题。
我通过延Schauder不尖提出的另一项改进:
Read this answer得到一个:
public Collection<User> findByNames(Collection<String> names) { return session.createCriteria(User.class). add(Restrictions.in("name", names)).list(); }
进一步的改进可以指定一些用户采集的时候不会偷懒进行更好的选择。
最后也是最重要的一个对我来说是:用一个列表代替我的SortedSet项目,做的getItems方法如下:
Set set = new LinkedHashSet(items); items.clear(); items.addAll(set); Collections.sort(items, itemComparator); return Collections.unmodifiableCollection(items);
与,Hibernate可以在项目收集工作(即添加)而不从数据库加载整个集合。
@Pascal Thivent和@Jens Schauder不:一堆感谢的!对不起,我只能接受一个答案: -/
有用的日志记录设置:
log4j.logger.org.hibernate.tool.hbm2ddl=INFO, StdoutApp
log4j.logger.org.hibernate.SQL=INFO, StdoutApp
# additionally provide the information which parameters will be bound:
log4j.logger.org.hibernate.type=TRACE
。
*(...)因为数据库已经有一个索引,因为我唯一的约束注释*:这很可能。你真的需要检查查询计划。 – 2010-06-15 21:28:36
好的。真的非常感谢你的评论!现在表现很合理。查看更新的问题。 – Karussell 2010-06-16 07:52:02