Oracle 数据库 - count(0) 运行 是否比 rownum < 500 快

Oracle database - Does count(0) run faster than rownum < 500

我想优化数据库中的某个查询,如果结果 > 500,则不要 运行 查询。

这 2 种方法中最快的方法是什么:

1)

list = createNativeQuery("select count(0) from (select * from table where rownum <= 501)")
if(list.size() > 500) throw error;
else runQuery();

或 2)

list = createNativeQuery("select * from table where rownum <= 501")
if(list.size() > 500) throw error;

与实际获取所有行并计算结果大小相比,计数查询是否总体上更快并且优化为 运行 更快?

编辑: 在第一种情况下,如果 count(0) returns size < 500,那么我必须重新 运行 查询,在我的例子中,我有一个复杂的 where 子句。如果我的子查询需要大约 10 秒,那么在场景 1 中它将需要大约 20 秒)。我的问题是,如果子查询需要 ~10s,子查询中的 select count(0) 是否需要,例如~1s 因为 oracle 的索引和优化?

比较以下两个查询:

select * from table where rownum <= 501
select count(*) from table where rownum <= 501

一般来说,这两种情况都需要数据库接触 table 中的 501 条记录(或更少)。从这个角度来看,这两个查询的性能应该大致相似。我预计 select count(*) 的表现不会比 select * 差。 但是,通过调用第一个查询,您可能会将大量数据发送回您的 Java 代码。这本身就有成为性能问题的风险。数据库非常擅长计算记录,但 Java 代码却不那么擅长。第二个查询似乎更适合您的用例。

请查看this great SO post了解更多信息。

第一种方法更好,因为您不需要从 table 到客户端的 select 行 在 SQL 中看到这个加上:

第一名:

SQL> SET AUTOTRACE ON STATISTICS
SQL> select count(0) from (select * from all_tables where rownum <= 501);

  COUNT(0)
----------
       501


Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
       1606  consistent gets
          0  physical reads
          0  redo size
        423  bytes sent via SQL*Net to client
        419  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          1  sorts (memory)
          0  sorts (disk)
          1  rows processed

第二名: 418 行 selected.

select * from table where rownum <= 501;
Statistics
----------------------------------------------------------
      9  recursive calls
      0  db block gets
    855  consistent gets
      0  physical reads
      0  redo size
  25012  bytes sent via SQL*Net to client
    716  bytes received via SQL*Net from client
     29  SQL*Net roundtrips to/from client
      1  sorts (memory)
      0  sorts (disk)
    418  rows processed

SQL>

注意字节数

423 in 1st approach vs 25012 in 2nd

第三 我不确定你项目的逻辑,但也许

select count(*) from all_tables

是获取行数最简单的方法,如果行数大于 501,则 运行 根本不需要查询

SQL> select count(*) from all_tables;

  COUNT(*)
----------
      1711


Statistics
----------------------------------------------------------
          8  recursive calls
          0  db block gets
       2557  consistent gets
          0  physical reads
        124  redo size
        423  bytes sent via SQL*Net to client
        419  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          1  sorts (memory)
          0  sorts (disk)
          1  rows processed

SQL>