database 检查数据库表中是否有某些记录的最快方法?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2131168/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 07:35:50  来源:igfitidea点击:

The fastest way to check if some records in a database table?

databaseoraclehibernate

提问by Sawyer

I have a huge table to work with . I want to check if there are some records whose parent_id equals my passing value . currently what I implement this is by using "select count(*) from mytable where parent_id = :id"; if the result > 0 , means the they do exist.

我有一张大桌子要处理。我想检查是否有一些记录的 parent_id 等于我的传递值。目前我是通过使用“select count(*) from mytable where parent_id = :id”来实现的;如果结果 > 0 ,则表示它们确实存在。

Because this is a very huge table , and I don't care what's the exactly number of records that exists , I just want to know whether it exists , so I think count(*) is a bit inefficient.

因为这是一个非常大的表,我不在乎存在的记录的确切数量是多少,我只想知道它是否存在,所以我认为 count(*) 有点低效。

How do I implement this requirement in the fastest way ? I am using Oracle 10.

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

#

According to hibernate Tips & Tricks https://www.hibernate.org/118.html#A2

根据 hibernate Tips & Tricks https://www.hibernate.org/118.html#A2

It suggests to write like this :

它建议这样写:

Integer count = (Integer) session.createQuery("select count(*) from ....").uniqueResult();

Integer count = (Integer) session.createQuery("select count(*) from ....").uniqueResult();

I don't know what's the magic of uniqueResult() here ? why does it make this fast ?

我不知道这里的 uniqueResult() 有什么魔力?为什么它这么快?

Compare to "select 1 from mytable where parent_id = passingId and rowrum < 2 " , which is more efficient ?

与“select 1 from mytable where parent_id=passingId and rowrum < 2”相比,哪个更有效?

回答by Nick Pierpoint

An EXISTS query is the one to go for if you're not interested in the number of records:

如果您对记录数不感兴趣,可以使用 EXISTS 查询:

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

This will return 'Y' if a record exists and nothing otherwise.

如果记录存在,则返回“Y”,否则返回。

[In terms of your question on Hibernate's "uniqueResult" - all this does is return a single object when there is only one object to return - instead of a set containing 1 object. If multiple results are returned the method throws an exception.]

[就您对 Hibernate 的“uniqueResult”的问题而言 - 所有这一切都是在只有一个对象要返回时返回一个对象 - 而不是包含 1 个对象的集合。如果返回多个结果,该方法将引发异常。]

回答by meriton

select count(*) should be lighteningly fast if you have an index, and if you don't, allowing the database to abort after the first match won't help much.

如果您有索引,则 select count(*) 应该快得惊人,如果没有,则允许数据库在第一次匹配后中止将无济于事。

But since you asked:

但既然你问:

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

(Some syntax errors to be expected, since I don't have a hibernate to test against on this computer)

(预期会出现一些语法错误,因为我没有在这台计算机上测试的休眠状态)

For Oracle, maxResults is translated into rownum by hibernate.

对于 Oracle,maxResults 被 hibernate 转换成 rownum。

As for what uniqueResult() does, read its JavaDoc! Using uniqueResult instead of list() has no performance impact; if I recall correctly, the implementation of uniqueResult delegates to list().

至于 uniqueResult() 的作用,请阅读它的 JavaDoc!使用 uniqueResult 而不是 list() 对性能没有影响;如果我没记错的话,uniqueResult 的实现委托给 list()。

回答by Adam Musch

There's no real difference between:

之间没有真正的区别:

select 'y' 
  from dual 
 where exists (select 1 
                 from child_table 
                where parent_key = :somevalue)

and

select 'y' 
  from mytable 
 where parent_key = :somevalue 
   and rownum = 1;

... at least in Oracle10gR2 and up. Oracle's smart enough in that release to do a FAST DUAL operation where it zeroes out any real activity against it. The second query would be easier to port if that's ever a consideration.

...至少在 Oracle10gR2 及更高版本中。Oracle 在该版本中足够聪明,可以执行 FAST DUAL 操作,将针对它的任何实际活动归零。如果考虑到这一点,则第二个查询将更容易移植。

The real performance differentiator is whether or not the parent_key column is indexed. If it's not, then you should run something like:

真正的性能差异在于 parent_key 列是否被索引。如果不是,那么你应该运行如下:

select 'y' 
  from dual 
 where exists (select 1 
                 from parent_able 
                where parent_key = :somevalue)

回答by Thilo

First of all, you need an index on mytable.parent_id.

首先,你需要一个关于 mytable.parent_id 的索引。

That should make your query fast enough, even for big tables (unless there are also a lot of rows with the same parent_id).

这应该使您的查询足够快,即使对于大表也是如此(除非还有很多具有相同 parent_id 的行)。

If not, you could write

如果没有,你可以写

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

which would return a single row containing 1, or no row at all. It does not need to count the rows, just find one and then quit. But this is Oracle-specific SQL (because of rownum), and you should rather not.

这将返回包含 1 的单行,或者根本没有行。它不需要计算行数,只需找到一个然后退出。但这是特定于 Oracle 的 SQL(因为有 rownum),您不应该这样做。

回答by bertolami

For DB2 there is something like select * from mytable where parent_id = ? fetch first 1 row only. I assume that something similar exists for oracle.

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

回答by MinhD

This query will return 1 if any record exists and 0 otherwise:

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

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

It could help when you need to check table data statistics, regardless table size and any performance issue.

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