我有一张可以使用的大桌子。我想检查是否有一些记录的parent_id等于我的传递值。 目前我实现的是使用“mytable中的select count(*)where parent_id =:id”;如果结果> 0,表示它们确实存在。
因为这是一个非常庞大的表,我不关心存在的记录的确切数量,我只想知道它是否存在,所以我认为count(*)效率有点低。
如何以最快的方式实现此要求?我正在使用Oracle 10。
#根据hibernate提示&欺骗https://www.hibernate.org/118.html#A2
建议像这样写:
整数计数=(整数)session.createQuery(“select count(*)from ....”)。uniqueResult();
我不知道uniqueResult()的神奇之处在哪里?为什么这么快?
比较“从mytable中选择1,其中parent_id = passingId和rowrum< 2”,哪个更有效?
答案 0 :(得分:11)
如果您对记录数量不感兴趣,可以选择EXISTS查询:
select 'Y' from dual where exists (select 1 from mytable where parent_id = :id)
如果记录存在,则返回“Y”,否则返回。
[关于Hibernate的“uniqueResult”的问题 - 当只有一个对象要返回时,所有这一切都返回一个对象 - 而不是一个包含1个对象的集合。如果返回多个结果,则该方法抛出异常。]
答案 1 :(得分:5)
select count(*)应该快得多,如果你没有,那么允许数据库在第一次匹配后中止将无济于事。
但是你问:
boolean exists = session.createQuery("select parent_id from Entity where parent_id=?")
.setParameter(...)
.setMaxResults(1)
.uniqueResult()
!= null;
(预计会出现一些语法错误,因为我没有在这台计算机上进行hibernate测试)
对于Oracle,maxResults由hibernate转换为rownum。
对于uniqueResult()的作用,请阅读它的JavaDoc!使用uniqueResult而不是list()没有性能影响;如果我没记错的话,uniqueResult的实现委托给list()。
答案 2 :(得分:4)
之间没有真正的区别:
select 'y'
from dual
where exists (select 1
from child_table
where parent_key = :somevalue)
和
select 'y'
from mytable
where parent_key = :somevalue
and rownum = 1;
...至少在Oracle10gR2及以上。 Oracle在该版本中足够聪明,可以执行FAST DUAL操作,将任何真正的活动归零。如果需要考虑的话,第二个查询将更容易移植。
真正的性能差异在于是否对parent_key列编制索引。如果不是,那么你应该运行类似的东西:
select 'y'
from dual
where exists (select 1
from parent_able
where parent_key = :somevalue)
答案 3 :(得分:2)
首先,您需要mytable.parent_id上的索引。
这应该使您的查询足够快,即使对于大表(除非还有很多行具有相同的parent_id)。
如果没有,你可以写
select 1 from mytable where parent_id = :id and rownum < 2
将返回包含1的单行,或根本不返回任何行。它不需要计算行数,只需找到一行然后退出。但这是特定于Oracle的SQL(因为rownum),你不应该这样做。
答案 4 :(得分:0)
对于DB2,有select * from mytable where parent_id = ? fetch first 1 row only
之类的东西。我假设oracle存在类似的东西。
答案 5 :(得分:0)
如果存在任何记录,则此查询将返回1,否则返回0:
SELECT COUNT(1) FROM (SELECT 1 FROM mytable WHERE ROWNUM < 2);
当您需要检查表数据统计信息时,无论表大小和性能问题如何,它都会有所帮助。