我注意到在Oracle中,查询
SELECT COUNT(*) FROM sometable;
Run Code Online (Sandbox Code Playgroud)
对于大型桌来说非常慢.它似乎是数据库,它实际上遍历每一行并一次递增一个计数器.我认为表中某处有一个计数器表有多少行.
因此,如果我想检查Oracle中表中的行数,那么最快的方法是什么?
Jef*_*emp 58
如果您只想粗略估计,可以从样本中推断:
SELECT COUNT(*) * 100 FROM sometable SAMPLE (1);
为了提高速度(但精度较低),您可以减小样本量:
SELECT COUNT(*) * 1000 FROM sometable SAMPLE (0.1);
为了获得更高的速度(但精度更高),您可以使用逐块采样:
SELECT COUNT(*) * 100 FROM sometable SAMPLE BLOCK (1);
小智 49
这适用于大型表格.
SELECT NUM_ROWS FROM ALL_TABLES WHERE TABLE_NAME = 'TABLE_NAME_IN_UPPERCASE';
Run Code Online (Sandbox Code Playgroud)
对于中小型表,以下都可以.
SELECT COUNT(Primary_Key) FROM table_name;
Run Code Online (Sandbox Code Playgroud)
干杯,
Vin*_*rat 29
想一想:数据库真的必须去每一行才能做到这一点.在多用户环境中,我COUNT(*)
可能与您的不同COUNT(*)
.为每个会话设置一个不同的计数器是不切实际的,因此你可以按字面计算行数.大多数情况下,你的查询中都会有WHERE子句或JOIN,所以你的假设计数器具有实用价值.
但是有一些方法可以加快速度:如果在NOT NULL列上有一个INDEX,Oracle将计算索引的行而不是表.在适当的关系模型中,所有表都有一个主键,因此COUNT(*)
将使用主键的索引.
位图索引具有NULL行的条目,因此如果有一个位图索引,COUNT(*)将使用位图索引.
APC*_*APC 13
如果表在NOT NULL列上有索引,则COUNT(*)将使用该列.否则,它将执行全表扫描.请注意,索引不必是UNIQUE,它必须是NOT NULL.
这是一张桌子......
SQL> desc big23
Name Null? Type
----------------------------------------- -------- ---------------------------
PK_COL NOT NULL NUMBER
COL_1 VARCHAR2(30)
COL_2 VARCHAR2(30)
COL_3 NUMBER
COL_4 DATE
COL_5 NUMBER
NAME VARCHAR2(10)
SQL>
Run Code Online (Sandbox Code Playgroud)
首先,我们将做一个没有索引的计数....
SQL> explain plan for
2 select count(*) from big23
3 /
Explained.
SQL> select * from table(dbms_xplan.display)
2 /
select * from table)dbms_xplan.display)
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------
Plan hash value: 983596667
--------------------------------------------------------------------
| Id | Operation | Name | Rows | Cost (%CPU)| Time |
--------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 1618 (1)| 00:00:20 |
| 1 | SORT AGGREGATE | | 1 | | |
| 2 | TABLE ACCESS FULL| BIG23 | 472K| 1618 (1)| 00:00:20 |
--------------------------------------------------------------------
Note
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------
- dynamic sampling used for this statement
13 rows selected.
SQL>
Run Code Online (Sandbox Code Playgroud)
不,我们在列上创建一个可以包含NULL条目的索引......
SQL> create index i23 on big23(col_5)
2 /
Index created.
SQL> delete from plan_table
2 /
3 rows deleted.
SQL> explain plan for
2 select count(*) from big23
3 /
Explained.
SQL> select * from table(dbms_xplan.display)
2 /
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------
Plan hash value: 983596667
--------------------------------------------------------------------
| Id | Operation | Name | Rows | Cost (%CPU)| Time |
--------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 1618 (1)| 00:00:20 |
| 1 | SORT AGGREGATE | | 1 | | |
| 2 | TABLE ACCESS FULL| BIG23 | 472K| 1618 (1)| 00:00:20 |
--------------------------------------------------------------------
Note
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------
- dynamic sampling used for this statement
13 rows selected.
SQL>
Run Code Online (Sandbox Code Playgroud)
最后让我们在NOT NULL列上构建索引....
SQL> drop index i23
2 /
Index dropped.
SQL> create index i23 on big23(pk_col)
2 /
Index created.
SQL> delete from plan_table
2 /
3 rows deleted.
SQL> explain plan for
2 select count(*) from big23
3 /
Explained.
SQL> select * from table(dbms_xplan.display)
2 /
PLAN_TABLE_OUTPUT
---------------------------------------------------------------------
Plan hash value: 1352920814
----------------------------------------------------------------------
| Id | Operation | Name | Rows | Cost (%CPU)| Time |
----------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 326 (1)| 00:00:04 |
| 1 | SORT AGGREGATE | | 1 | | |
| 2 | INDEX FAST FULL SCAN| I23 | 472K| 326 (1)| 00:00:04 |
----------------------------------------------------------------------
Note
PLAN_TABLE_OUTPUT
----------------------------------------------------------------------
- dynamic sampling used for this statement
13 rows selected.
SQL>
Run Code Online (Sandbox Code Playgroud)
选项1:在非空列上存在可用于扫描的索引.或者创建基于函数的索引:
create index idx on t(0);
Run Code Online (Sandbox Code Playgroud)
然后可以扫描这个以计算.
选项2:如果已打开监视,则检查监视视图USER_TAB_MODIFICATIONS并将相关值添加/减去表统计信息.
选项3:对大型表的快速估计调用SAMPLE子句...例如......
SELECT 1000*COUNT(*) FROM sometable SAMPLE(0.1);
Run Code Online (Sandbox Code Playgroud)
选项4:使用物化视图来维护计数(*).虽然强大的药物.
嗯...
您可以创建快速刷新物化视图来存储计数.
例:
create table sometable (
id number(10) not null primary key
, name varchar2(100) not null);
create materialized view log on sometable with rowid including new values;
create materialized view sometable_count
refresh on commit
as
select count(*) count
from sometable;
insert into sometable values (1,'Raymond');
insert into sometable values (2,'Hans');
commit;
select count from sometable_count;
Run Code Online (Sandbox Code Playgroud)
它会减慢桌面上的突变,但计数会变得更快.
归档时间: |
|
查看次数: |
172418 次 |
最近记录: |