2010-01-25 98 views
10

我有一张巨大的桌子可以使用。我想检查是否有一些parent_id等于我的传递值的记录。 目前我实现这个是通过使用“select count(*)from mytable where parent_id =:id”;如果结果> 0,意味着它们确实存在。因为这是一个非常大的表格,我不在乎什么是存在的记录的确切数量,我只是想知道它是否存在,所以我认为count(*)有点低效。检查数据库表中的某些记录的最快方法是什么?

如何以最快的方式实现此要求?我使用的是Oracle 10

根据冬眠提示&技巧https://www.hibernate.org/118.html#A2

这表明,以这样写:

整型数=(整数)session.createQuery(“SELECT COUNT(* )from ....“)。uniqueResult();

我不知道uniqueResult()在这里有什么魔力?为什么它使这个速度更快?

比较“选择1从mytable where parent_id = passingId和rowrum < 2”,这样更有效率吗?

回答

9

一个EXISTS查询是一个去,如果你不感兴趣的记录数:

select 'Y' from dual where exists (select 1 from mytable where parent_id = :id) 

这将返回“Y”,如果记录存在并没有什么其他方式。

[在上Hibernate的“uniqueResult”你的问题而言 - 这一切都为返回一个对象时,只有一个对象返回 - 而不是包含1名对象的一组。如果多个结果返回的方法抛出一个异常]

+0

您甚至不需要查询DUAL - 从mytable中选择'Y',其中parent_id =:id AND ROWNUM = 1'给出相同的结果。 – 2010-01-26 08:47:16

+0

是的 - 只是不喜欢“ROWNUM = 1” - 并不像EXISTS查询那样透明。尽管如此。 – 2010-01-26 11:54:04

2

首先,您需要mytable.parent_id上的索引。

这应该使您的查询速度不够快,即使是大表(除非也有很多行与同PARENT_ID)。

如果没有,你可以写

select 1 from mytable where parent_id = :id and rownum < 2 

这将返回一个包含1单行,或没有行的。它不需要对行进行计数,找到一个然后退出。但是这是Oracle特有的SQL(因为rownum),你不应该这样做。

+0

+1对于索引推荐 – 2010-01-25 11:13:52

+2

我想去一个EXISTS查询我认为 - 对需求更加透明:select 2 from dual where exists(select from mytable where parent_id =:id) – 2010-01-25 13:00:17

0

对于DB2有类似select * from mytable where parent_id = ? fetch first 1 row only。我认为oracle有类似的东西存在。

+1

所有SQl方言不同 - 你不能认为有类似的东西例如Oracle有rownum,在Sybase中并不存在,我认为在DB2 – Mark 2010-01-25 10:25:59

+2

中,rownum概念是我称之为“类似”的概念,因为它涵盖了相同的用例,即获得最前n个记录(http://www.petefreitag。 com/item/59.cfm) – bertolami 2010-01-25 10:39:21

+0

re:top n。 rownum的一个问题是,它在任何排序完成之前都会被评估,因此它不是真正的“顶级”n。 – Thilo 2010-01-25 10:54:27

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) 
5

SELECT COUNT(*)应lighteningly快,如果你有一个指标,如果你不这样做,允许数据库中止第一场比赛胜利之后没什么帮助。

但既然你问:

boolean exists = session.createQuery("select parent_id from Entity where parent_id=?") 
         .setParameter(...) 
         .setMaxResults(1) 
         .uniqueResult() 
       != null; 

(可以预料的一些语法错误,因为我没有休眠来测试针对此计算机上)

对于Oracle,maxResults,则翻译成rownum通过休眠。

至于uniqueResult()的功能,请阅读它的JavaDoc!使用uniqueResult而不是list()不会影响性能;如果我没有记错,执行uniqueResult委托给list()。

+0

+1 for setMaxResults – Thilo 2010-01-26 00:50:59

0

如果任何记录存在,否则为0这个查询将返回1:

SELECT COUNT(1) FROM (SELECT 1 FROM mytable WHERE ROWNUM < 2); 

当你需要检查表数据统计它可以帮助,无论表规模和任何性能问题。

相关问题