[size=9.0pt]一个大表的COUNT,究竟能有多快呢?除去类似物化视图的做法,我们所能做到的极限能有多快?下面例子是一个大表计数的示例,从最开始的124秒,到最终的0.03秒。
[size=9.0pt]
[size=9.0pt]关键字: B树索引、位图索引、IFFS、COUNT、索引压缩、并行
[size=9.0pt]
[size=9.0pt](1).[size=9.0pt]数据准备
[size=9.0pt]数据量
[size=9.0pt]select count(*) from t2; =>102400000 //1[size=9.0pt]亿多条
[size=9.0pt]数据对象大小
[size=9.0pt]select bytes/1024/1024 from user_segments where segment_name='T2';
[size=9.0pt]BYTES/1024/1024
[size=9.0pt]---------------
[size=9.0pt] 10972 //10G[size=9.0pt]多
[size=9.0pt]数据结构
[size=9.0pt][hf@ora10g] SQL> desc T2;
[size=9.0pt] Name Null? Type
[size=9.0pt] ------------------------------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------
[size=9.0pt] OWNER VARCHAR2(30)
[size=9.0pt] OBJECT_NAME VARCHAR2(128)
[size=9.0pt] SUBOBJECT_NAME VARCHAR2(30)
[size=9.0pt] OBJECT_ID NUMBER
[size=9.0pt] DATA_OBJECT_ID NUMBER
[size=9.0pt] OBJECT_TYPE VARCHAR2(19)
[size=9.0pt] CREATED DATE
[size=9.0pt] LAST_DDL_TIME DATE
[size=9.0pt] TIMESTAMP VARCHAR2(19)
[size=9.0pt] STATUS VARCHAR2(7)
[size=9.0pt] TEMPORARY VARCHAR2(1)
[size=9.0pt] GENERATED VARCHAR2(1)
[size=9.0pt] SECONDARY VARCHAR2(1)
[size=9.0pt] ID NOT NULL NUMBER(38)
[size=9.0pt]典型数据
[size=9.0pt]select * from t2 where rownum<6;
[size=9.0pt]OWNER OBJECT_NAM SUBOBJECT_ OBJECT_ID DATA_OBJECT_ID OBJECT_TYPE CREATED LAST_DDL_TIME TIMESTAMP STATUS T G S ID
[size=9.0pt]----- ---------- ---------- ---------- -------------- -------------------------------------- ------------------- ------------------- ------- - - -----------
[size=9.0pt]SYS ICOL$ 20 2 TABLE 2008-03-12 00:39:48 2008-03-1200:58:12 2008-03-12:00:39:48 VALID N NN 1
[size=9.0pt]SYS I_USER1 44 44 INDEX 2008-03-12 00:39:48 2008-03-1200:39:48 2008-03-12:00:39:48 VALID N NN 2
[size=9.0pt]SYS CON$ 28 28 TABLE 2008-03-12 00:39:48 2008-03-1201:08:43 2008-03-12:00:39:48 VALID N NN 3
[size=9.0pt]SYS UNDO$ 15 15 TABLE 2008-03-12 00:39:48 2008-03-1200:39:48 2008-03-12:00:39:48 VALID N NN 4
[size=9.0pt]SYS C_COBJ# 29 29 CLUSTER 2008-03-12 00:39:48 2008-03-1200:39:48 2008-03-12:00:39:48 VALID N NN 5
[size=9.0pt](2).[size=9.0pt]全表扫描(124秒)
[size=9.0pt]select count(*) from t2;
[size=9.0pt]Elapsed: 00:02:04.09
[size=9.0pt]-------------------------------------------------------------------
[size=9.0pt]| Id | Operation | Name | Rows | Cost (%CPU)| Time |
[size=9.0pt]-------------------------------------------------------------------
[size=9.0pt]| 0 | SELECT STATEMENT | | 1 | 381K (1)| 01:16:19 |
[size=9.0pt]| 1 | SORT AGGREGATE | | 1 | | |
[size=9.0pt]| 2 | TABLE ACCESS FULL| T2 | 102M| 381K (1)| 01:16:19 |
[size=9.0pt]-------------------------------------------------------------------
[size=9.0pt]Statistics
[size=9.0pt]----------------------------------------------------------
[size=9.0pt] 1 recursive calls
[size=9.0pt] 0 db block gets
[size=9.0pt] 1400379 consistent gets
[size=9.0pt] 1068862 physical reads
[size=9.0pt](3).[size=9.0pt]主键索引(33秒)
[size=9.0pt]alter table t2 add constraint pk_t2 primary key(id);
[size=9.0pt]exec dbms_stats.gather_index_stats('hf', 'pk_t2', estimate_percent =>10);
[size=9.0pt]select count(*) from t2;
[size=9.0pt]Elapsed: 00:00:33.18
[size=9.0pt]-----------------------------------------------------------------------
[size=9.0pt]| Id | Operation | Name | Rows | Cost (%CPU)| Time |
[size=9.0pt]-----------------------------------------------------------------------
[size=9.0pt]| 0 | SELECT STATEMENT | | 1 | 64271 (2)| 00:12:52 |
[size=9.0pt]| 1 | SORT AGGREGATE | | 1 | | |
[size=9.0pt]| 2 | INDEX FAST FULL SCAN| PK_T2 | 102M| 64271 (2)| 00:12:52 |
[size=9.0pt]-----------------------------------------------------------------------
[size=9.0pt]Statistics
[size=9.0pt]----------------------------------------------------------
[size=9.0pt] 1 recursive calls
[size=9.0pt] 0 db block gets
[size=9.0pt] 228654 consistent gets
[size=9.0pt] 205137 physical reads
[size=9.0pt](4).[size=9.0pt]常数索引(29秒)
[size=9.0pt]create index idx_0 on t2(0);
[size=9.0pt]exec dbms_stats.gather_index_stats('hf', 'idx_0', estimate_percent =>10);
[size=9.0pt]select count(*) from t2;
[size=9.0pt]Elapsed: 00:00:28.92
[size=9.0pt]-----------------------------------------------------------------------
[size=9.0pt]| Id | Operation | Name | Rows | Cost (%CPU)| Time |
[size=9.0pt]-----------------------------------------------------------------------
[size=9.0pt]| 0 | SELECT STATEMENT | | 1 | 49601 (2)| 00:09:56 |
[size=9.0pt]| 1 | SORT AGGREGATE | | 1 | | |
[size=9.0pt]| 2 | INDEX FAST FULL SCAN| IDX_0 | 102M| 49601 (2)| 00:09:56 |
[size=9.0pt]-----------------------------------------------------------------------
[size=9.0pt]Statistics
[size=9.0pt]----------------------------------------------------------
[size=9.0pt] 1 recursive calls
[size=9.0pt] 0 db block gets
[size=9.0pt] 185899 consistent gets
[size=9.0pt] 167726 physical reads
[size=9.0pt](5).[size=9.0pt]常数压缩索引(27秒)
[size=9.0pt]create index idx_0 on t2(0) compress;
[size=9.0pt]exec dbms_stats.gather_index_stats('hf', 'idx_0', estimate_percent =>10);
[size=9.0pt]select count(*) from t2;
[size=9.0pt]Elapsed: 00:00:27.85
[size=9.0pt]-----------------------------------------------------------------------
[size=9.0pt]| Id | Operation | Name | Rows | Cost (%CPU)| Time |
[size=9.0pt]-----------------------------------------------------------------------
[size=9.0pt]| 0 | SELECT STATEMENT | | 1 | 43812 (3)| 00:08:46 |
[size=9.0pt]| 1 | SORT AGGREGATE | | 1 | | |
[size=9.0pt]| 2 | INDEX FAST FULL SCAN| IDX_0 | 102M| 43812 (3)| 00:08:46 |
[size=9.0pt]-----------------------------------------------------------------------
[size=9.0pt]Statistics
[size=9.0pt]----------------------------------------------------------
[size=9.0pt] 1 recursive calls
[size=9.0pt] 0 db block gets
[size=9.0pt] 157636 consistent gets //[size=9.0pt]压缩后,减少了
[size=9.0pt] 141651 physical reads
[size=9.0pt](6).[size=9.0pt]位图索引(0.9秒)
[size=9.0pt]create bitmap index idx_status2 on t2(status);
[size=9.0pt]exec dbms_stats.gather_index_stats('hf', 'idx_status2', estimate_percent=> 10);
[size=9.0pt]select count(*) from t2;
[size=9.0pt]Elapsed: 00:00:00.9
[size=9.0pt]-------------------------------------------------------------------------------------
[size=9.0pt]| Id | Operation | Name | Rows | Cost (%CPU)| Time |
[size=9.0pt]-------------------------------------------------------------------------------------
[size=9.0pt]| 0 | SELECT STATEMENT | | 1 | 2262 (1)| 00:00:28 |
[size=9.0pt]| 1 | SORT AGGREGATE | | 1 | | |
[size=9.0pt]| 2 | BITMAP CONVERSION COUNT | | 102M| 2262 (1)| 00:00:28 |
[size=9.0pt]| 3 | BITMAP INDEX FAST FULL SCAN| IDX_STATUS2| | | |
[size=9.0pt]-------------------------------------------------------------------------------------
[size=9.0pt]Statistics
[size=9.0pt]----------------------------------------------------------
[size=9.0pt] 1 recursive calls
[size=9.0pt] 0 db block gets
[size=9.0pt] 2502 consistent gets //[size=9.0pt]大大减少
[size=9.0pt] 351 physical reads
[size=9.0pt](7).[size=9.0pt]位图索引+ 并行(0.03秒)
[size=9.0pt]alter index idx_status2 parallel 8;
[size=9.0pt]select count(*) from t2;
[size=9.0pt]Elapsed: 00:00:00.03
[size=9.0pt]----------------------------------------------------------------------------------------------------------------------
[size=9.0pt]| Id | Operation | Name | Rows | Cost (%CPU)| Time | TQ |IN-OUT| PQ Distrib |
[size=9.0pt]----------------------------------------------------------------------------------------------------------------------
[size=9.0pt]| 0 | SELECT STATEMENT | | 1 | 2206 (1)| 00:00:27 | | | |
[size=9.0pt]| 1 | SORT AGGREGATE | | 1 | | | | | |
[size=9.0pt]| 2 | PX COORDINATOR | | | | | | | |
[size=9.0pt]| 3 | PX SEND QC (RANDOM) | :TQ10000 | 1 | | | Q1,00 | P->S | QC (RAND) |
[size=9.0pt]| 4 | SORT AGGREGATE | | 1 | | | Q1,00 | PCWP | |
[size=9.0pt]| 5 | PX BLOCK ITERATOR | | 102M| 2206 (1)| 00:00:27 | Q1,00 | PCWC | |
[size=9.0pt]| 6 | BITMAP CONVERSION COUNT | | 102M| 2206 (1)| 00:00:27 | Q1,00 | PCWP | |
[size=9.0pt]| 7 | BITMAP INDEX FAST FULL SCAN|IDX_STATUS2 | | | | Q1,00 | PCWP | |
[size=9.0pt]----------------------------------------------------------------------------------------------------------------------
[size=9.0pt]Statistics
[size=9.0pt]----------------------------------------------------------
[size=9.0pt] 265 recursive calls
[size=9.0pt] 3 db block gets
[size=9.0pt] 3059 consistent gets //[size=9.0pt]有所增加,但并行还是能加快整体运行速度
[size=9.0pt] 0 physical reads
[size=9.0pt]
[size=9.0pt](8).总结来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/23884971/viewspace-767225/ ,如需转载,请注明出处,否则将追究法律责任。