ITPub博客

首页 > Linux操作系统 > Linux操作系统 > 优化案例——COUNT(*)从124秒到0.03秒

优化案例——COUNT(*)从124秒到0.03秒

原创 Linux操作系统 作者:北京大豆 时间:2013-07-26 18:18:45 0 删除 编辑
[i=s] 本帖最后由 北京大豆 于 2013-7-26 11:38 编辑

[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).总结

  • 位图索引可以按很高密度存储数据,因此往往比B树索引小很多。前提是基数比较小的情况下。
  • 位图索引是保存空值的,因此可以在COUNT中利用。
  • 周所周知的原因,位图索引是不太适合OLTP类型数据库。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/23884971/viewspace-767225/,如需转载,请注明出处,否则将追究法律责任。

上一篇: 没有了~
下一篇: 没有了~
请登录后发表评论 登录
全部评论

注册时间:2012-12-27

  • 博文量
    1
  • 访问量
    6643