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>
我想优化数据库中的某个查询,如果结果 > 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>