检查数据库表中某些记录的最快方法是什么?

时间:2010-01-25 09:03:42

标签: database oracle hibernate

我有一张可以使用的大桌子。我想检查是否有一些记录的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”,哪个更有效?

6 个答案:

答案 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);

当您需要检查表数据统计信息时,无论表大小和性能问题如何,它都会有所帮助。