Java hibernate最快的findByName查询是什么?
我相信我可以提高hibernate的以下findByName查询的性能:Java hibernate最快的findByName查询是什么?,java,database,performance,hibernate,Java,Database,Performance,Hibernate,我相信我可以提高hibernate的以下findByName查询的性能: public List<User> findByName(String name) { session.createCriteria(User.class).add(Restrictions.eq("name", name)).list(); } 我应该以哪种方式改进它,或者更重要的是:我应该首先以哪种方式改进它?我将需要这个类的所有集合(layz或不是)和dep的完整对象 或者,如果我想要几个用户对象(
public List<User> findByName(String name) {
session.createCriteria(User.class).add(Restrictions.eq("name", name)).list();
}
我应该以哪种方式改进它,或者更重要的是:我应该首先以哪种方式改进它?我将需要这个类的所有集合(layz或不是)和dep的完整对象
或者,如果我想要几个用户对象(并且知道几个名称),我可以改进它吗
更新1:
@Index注释没有提高性能,因为数据库已经有了索引,因为我的唯一约束注释:
@UniqueConstraint(columnNames = {"name"})
更新2:
public Collection<User> findByNames(Collection<String> names) {
return session.createCriteria(User.class).
add(Restrictions.in("name", names)).list();
}
为了得到更好的选择Set set = new LinkedHashSet(items);
items.clear();
items.addAll(set);
Collections.sort(items, itemComparator);
return Collections.unmodifiableCollection(items);
这样,hibernate就可以处理items集合(即添加),而无需从数据库加载整个集合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
.您没有提供足够的信息来完整回答问题,但以下是一些想法:
- 你能用身份证吗?Hibernate将为select by id准备查询,因此这些查询将(稍微)比其他查询快
- 名称的索引是否正确?对于这个查询,它应该有一个唯一的键(你暗示的是,你期望的是一个结果)。当然,这样的索引在插入、更新和删除时会降低性能
- 当我们谈到引用时,它取决于您所说的性能:语句返回之前的时间?那么您应该使用延迟加载。它使第一个语句更快,因此可能更快。当然,一旦你的参考文献脱水,你会有更多的陈述。否则(一些)急切的加载可能会更快,尽管这在很大程度上取决于细节
- 使用缓存,如果可以从缓存中检索引用,这可能特别有助于引用
- 调整数据库。给它足够的内存,让它能一直记住所有的东西
- 调整你的网络。对于如图所示的小查询,延迟可能是一个问题
- 通过将数据库与代码放在同一台计算机上来删除网络。假设它足够大
根据评论更新: 调整时,第一个问题是:我们需要调整什么? 是将标准转换为SQL语句吗?如果是这样的话,直接提供sql语句就可以完成这项工作 它是sql语句的实际执行吗?如果是这样,首先要确定由发布的代码生成的sql语句 我从未见过存储过程使事情更快的真实案例。当然,这并不意味着此类案件不存在。但是现代rdbms的优化器非常聪明 因此,为了正确地开始这项工作:设置日志记录,以便查看每个带有精确时间戳的sql语句。以及您正在调整的整个过程的开始和结束时间。如果这是关于数百次处决,你就得把事情搞糟 这将告诉您是否执行了sql语句,这占用了很多时间,以及是否是sql语句导致了问题 大多数情况下,sql语句的性能很差,但我们不应该急于下结论
关于多个名称部分的更新: 您可以使用非表达式:一次查找多个对象。这将比单个查询更快 在我的例子中,我知道名称是唯一的,但是向name属性添加索引注释并没有提高性能。瓶颈是
findByName
方法
我不会相信这个。。。直到你拿出一些数字证明我错了:)所以:
- 仔细检查索引是否已生成(检查DDL语句和数据库)。此查询需要此列上的索引
- 检查生成的查询的查询计划(应该类似于
)和执行时间SELECT*FROM USER u,其中u.NAME='foo'
以后,您可以考虑激活第二级缓存并缓存查询。但数据库才是起点(过早缓存东西只会隐藏真正的问题)
测量东西!如果你不能测量它,你就不能改进它--开尔文勋爵。很抱歉没有提供足够的信息。这是一个商业项目,我会尽量向您提供最大限度的信息,而不会让我的老板生气。第一:我不能改用id。我认为我可以使用本机sql查询或存储过程?这会提高性能吗?当表很小时,索引可能不会被使用,尽管它看起来像是一个完美的匹配。当然,完全有可能OP添加了注释,但没有更改模式:)@Jens Schauder:我应该如何更改模式?(我在运行drop+create架构之前
@LazyCollection(LazyCollectionOption.FALSE)
Set set = new LinkedHashSet(items);
items.clear();
items.addAll(set);
Collections.sort(items, itemComparator);
return Collections.unmodifiableCollection(items);
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