Saw*_*yer 10 database oracle hibernate
我有一张很大的桌子可供使用.我想检查是否有一些记录的parent_id等于我的传递值.目前我实现的是使用"mytable中的select count(*)where parent_id =:id"; 如果结果> 0,则表示它们确实存在.
因为这是一个非常庞大的表,我不关心存在的记录的确切数量,我只想知道它是否存在,所以我认为count(*)有点低效.
如何以最快的方式实现此要求?我正在使用Oracle 10.
#根据hibernate提示和技巧https://www.hibernate.org/118.html#A2
它建议像这样写:
整数count =(整数)session.createQuery("select count(*)from ....").uniqueResult();
我不知道uniqueResult()的神奇之处在哪里?为什么这么快?
比较"从mytable中选择1,其中parent_id = passingId和rowrum <2",哪个更有效?
Nic*_*int 11
如果您对记录数不感兴趣,则可以使用EXISTS查询:
select 'Y' from dual where exists (select 1 from mytable where parent_id = :id)
Run Code Online (Sandbox Code Playgroud)
如果记录存在,则返回"Y",否则返回任何内容.
[关于Hibernate的"uniqueResult"的问题 - 当只有一个对象要返回时,所有这一切都返回一个对象 - 而不是包含一个对象的集合.如果返回多个结果,则该方法会抛出异常.]
之间没有真正的区别:
select 'y'
from dual
where exists (select 1
from child_table
where parent_key = :somevalue)
Run Code Online (Sandbox Code Playgroud)
和
select 'y'
from mytable
where parent_key = :somevalue
and rownum = 1;
Run Code Online (Sandbox Code Playgroud)
...至少在 Oracle10gR2 及更高版本中。Oracle 在该版本中足够聪明,可以执行 FAST DUAL 操作,将任何针对它的实际活动归零。如果考虑到第二个查询会更容易移植。
真正的性能差异在于parent_key 列是否被索引。如果不是,那么你应该运行类似的命令:
select 'y'
from dual
where exists (select 1
from parent_able
where parent_key = :somevalue)
Run Code Online (Sandbox Code Playgroud)
如果你有一个索引,select count(*)应该是快速的,如果你没有,那么允许数据库在第一次匹配后中止将无济于事.
但既然你问:
boolean exists = session.createQuery("select parent_id from Entity where parent_id=?")
.setParameter(...)
.setMaxResults(1)
.uniqueResult()
!= null;
Run Code Online (Sandbox Code Playgroud)
(有些语法错误是预期的,因为我没有在这台计算机上进行hibernate测试)
对于Oracle,maxResults由hibernate转换为rownum.
至于uniqueResult()的作用,请阅读它的JavaDoc!使用uniqueResult而不是list()没有性能影响; 如果我没记错的话,将uniqueResult的实现委托给list().