通过多种来源,书籍和问题,我发现count(1)
和之间没有区别count(*)
.我找到的地方count(1)
比...更快count(*)
.但我真的不知道怎么样?据我所知,count(*)
计算rowid
并count(1)
计算1作为行数.因为rowid
18位数的字符需要更多时间吗?据我所知,尺寸是2还是38,速度无关紧要.
你们中的任何人都可以清楚我的怀疑.
eao*_*son 13
我相信count(1)
在旧版本的Oracle中曾经更快.但到目前为止,我非常确定优化器足够聪明,可以知道count(*)
并且count(1)
意味着您需要行数并创建适当的执行计划.
干得好:
create table t as select * from all_objects;
Table T created.
create index tindx on t( object_name );
Index TINDX created.
select count(*) from t;
COUNT(*)
----------
21534
select * from table(dbms_xplan.display_cursor( NULL, NULL, 'allstats last' ));
Plan hash value: 2940353011
--------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Reads |
--------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 1 |00:00:00.01 | 100 | 93 |
| 1 | SORT AGGREGATE | | 1 | 1 | 1 |00:00:00.01 | 100 | 93 |
| 2 | INDEX FAST FULL SCAN| TINDX | 1 | 18459 | 21534 |00:00:00.01 | 100 | 93 |
--------------------------------------------------------------------------------------------------
select count(1) from t;
COUNT(1)
----------
21534
Plan hash value: 2940353011
-----------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
-----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 1 |00:00:00.01 | 100 |
| 1 | SORT AGGREGATE | | 1 | 1 | 1 |00:00:00.01 | 100 |
| 2 | INDEX FAST FULL SCAN| TINDX | 1 | 18459 | 21534 |00:00:00.01 | 100 |
-----------------------------------------------------------------------------------------
Run Code Online (Sandbox Code Playgroud)
因此,它不仅足够聪明,而且知道它可以使用索引来优化此查询,但它对不同版本使用完全相同的执行计划(计划的值相同).
我认为这个谣言的起源是假设数据库必须在内部扩展*
到完整的列列表,因此count('Dracula')
巧妙地替换一些文字可以避免这种开销。但它没有,而且从来没有。我在 1990 年在 Oracle 6 周围第一次听到这种说法(另一个变体是您应该使用 PK 列),但当时情况并非如此。
标准证明之一(除了检查它是否真的对性能产生任何影响之外,它不会)是检查执行计划中count(1)
用于谓词的“谓词”部分:
SQL> select dummy from dual group by dummy having count(1) = 1
SQL> @xplan
Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production
Compatibility is set to 12.2.0.0.0
Plan hash value: 795860295
------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 2 | 3 (34)| 00:00:01 |
|* 1 | FILTER | | | | | |
| 2 | SORT GROUP BY NOSORT| | 1 | 2 | 3 (34)| 00:00:01 |
| 3 | TABLE ACCESS FULL | DUAL | 1 | 2 | 2 (0)| 00:00:01 |
------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter(COUNT(*)=1)
Run Code Online (Sandbox Code Playgroud)
请注意,优化器已替换COUNT(*)
.
所有count(1)
做的就是给你更多的按键输入,让你看起来像一个人谁相信谣言。
我已经在 Oracle 和其他一些 RDBMS 中测试了两个计算1M 行COUNT(*)
或的简单查询COUNT(1)
,但没有发现 Oracle 中存在任何差异。详细信息请参阅这篇文章。
然而,在 PostgreSQL 11.3 中,似乎COUNT(1)
慢了大约 10%,因为 PostgreSQL 不会将表达式转换为COUNT(*)
,因此在运行时检查每行的可为空性COUNT(1)
。
归档时间: |
|
查看次数: |
2026 次 |
最近记录: |