Oracle count的优化-避免全表扫描

2024-05-10 1479阅读

Oracle  count的优化-避免全表扫描

select count(*) from t1;

这句话比较简单,但很有玄机!对这句话运行的理解,反映了你对数据库的理解深度!

建立实验的大表他t1

SQL> conn scott/tiger

已连接。

SQL> drop table t1 purge;

表已删除。

SQL> create table t1 as select * from emp where 0=9;

表已创建。

SQL> insert into t1 select * from emp;

已创建14行。

SQL>  insert into t1 select * from t1;

已创建14行。

SQL> /

已创建28行。

SQL> /

已创建56行。

SQL> /

已创建112行。

SQL> /

已创建224行。

SQL> /

已创建448行。

SQL> /

已创建896行。

SQL> /

已创建1792行。

SQL> /

已创建3584行。

SQL> /

已创建7168行。

SQL> /

已创建14336行。

SQL> /

已创建28672行。

SQL> /

已创建57344行。

SQL> commit;

提交完成。

收集统计信息

SQL> execute dbms_stats.gather_table_stats('SCOTT','T1');

PL/SQL 过程已成功完成。

SQL> SET AUTOT TRACE EXP

SQL> SELECT COUNT(*) FROM T1;

执行计划

--------------------------------------------------                                

| Id  | Operation          | Name | Rows  | Cost (%CPU)| Time     |                                 

-------------------------------------------------------------------                                 

|   0 | SELECT STATEMENT   |      |     1 |   124 (4)| 00:00:02 |                                 

|   1 |  SORT AGGREGATE    |      |     1 |          |          |                                 

|   2 |   TABLE ACCESS FULL| T1   |   116K|   124 (4)| 00:00:02 |                                 

-----------------------------------------------------

代价为124,运行的计划为全表扫描。              

SQL> DELETE T1 WHERE DEPTNO=10;

已删除24576行。

SQL> COMMIT;

提交完成。

SQL> execute dbms_stats.gather_table_stats('SCOTT','T1');

PL/SQL 过程已成功完成。

SQL> SELECT COUNT(*) FROM T1;

执行计划

-----------------------------------------------------

| Id  | Operation          | Name | Rows  | Cost (%CPU)| Time     |                                 

-------------------------------------------------------------------                                 

|   0 | SELECT STATEMENT   |      |     1 |   123 (3)| 00:00:02 |                                 

|   1 |  SORT AGGREGATE    |      |     1 |          |          |                                 

|   2 |   TABLE ACCESS FULL| T1   | 90286 |  123  (3)| 00:00:02 |                                 

-----------------------------------------------------

SQL> --1.降低高水位

SQL> alter table t1 move tablespace users;

表已更改。

SQL> execute dbms_stats.gather_table_stats('SCOTT','T1');

PL/SQL 过程已成功完成。

SQL> SELECT COUNT(*) FROM T1;

执行计划

-----------------------------------------------------

| Id  | Operation          | Name | Rows  |Cost (%CPU)| Time   |                                 

-------------------------------------------------------------------                                 

|   0 | SELECT STATEMENT   |      |     1 |   102 (3)| 00:00:02 |                                 

|   1 |  SORT AGGREGATE    |      |     1 |          |          |                                 

|   2 |   TABLE ACCESS FULL| T1   | 90667 |   102 (3)| 00:00:02 |                                 

-----------------------------------------------------                          

代价为102,降低了

SQL> --2.修改pctfree

SQL> alter table t1 pctfree 0;

表已更改。

SQL> alter table t1 move tablespace users;

表已更改。

SQL> execute dbms_stats.gather_table_stats('SCOTT','T1');

PL/SQL 过程已成功完成。

SQL> SELECT COUNT(*) FROM T1;

执行计划

----------------------------------------------------------                                          

Plan hash value: 3724264953                                                                         

                                                                                                    

-------------------------------------------------------------------                                 

| Id  | Operation          | Name | Rows  | Cost (%CPU)| Time     |                                 

-------------------------------------------------------------------                                 

|   0 | SELECT STATEMENT   |      |     1 |    92   (4)| 00:00:02 |                                 

|   1 |  SORT AGGREGATE    |      |     1 |            |          |                                 

|   2 |   TABLE ACCESS FULL| T1   | 91791 |    92   (4)| 00:00:02 |                                 

-------------------------------------------------------------------                                 

代价为92,降低了10%

SQL> --3.参数db_file_multiblock_read_count=64

SQL> --4.建立b*tree类型的索引

SQL> create index i1 on t1(empno);

索引已创建。

SQL> execute dbms_stats.gather_index_stats('SCOTT','I1');

PL/SQL 过程已成功完成。

SQL> SELECT COUNT(*) FROM T1;

执行计划

----------------------------------------------------------                                          

Plan hash value: 3724264953                                                                         

                                                                                                    

-------------------------------------------------------------------                                 

| Id  | Operation          | Name | Rows  | Cost (%CPU)| Time     |                                 

-------------------------------------------------------------------                                 

|   0 | SELECT STATEMENT   |      |     1 |    92   (4)| 00:00:02 |                                 

|   1 |  SORT AGGREGATE    |      |     1 |            |          |                                 

|   2 |   TABLE ACCESS FULL| T1   | 91791 |    92   (4)| 00:00:02 |                                 

-------------------------------------------------------------------                                 

为什么没有使用我们建立的索引,因为null不进入普通的索引!

SQL> alter table t1 modify(empno not null);

表已更改。

SQL> SELECT COUNT(*) FROM T1;

执行计划

----------------------------------------------------------                                          

Plan hash value: 129980005                                                                          

                                                                                                    

----------------------------------------------------------------------                              

| Id  | Operation             | Name | Rows  | Cost (%CPU)| Time     |                              

----------------------------------------------------------------------                              

|   0 | SELECT STATEMENT      |      |     1 |    36   (6)| 00:00:01 |                              

|   1 |  SORT AGGREGATE       |      |     1 |            |          |                              

|   2 |   INDEX FAST FULL SCAN| I1   | 91791 |    36   (6)| 00:00:01 |                              

----------------------------------------------------------------------                              

我们的索引起到了很大的作用!

SQL> --5.使用并行查询的特性

                                

强制全表扫描,屏蔽索引

SQL> select /*+ full(t1) parallel(t1 2) */ COUNT(*) FROM T1;

执行计划

----------------------------------------------------------------------------------------

| Id  | Operation    | Name     | Rows  | Cost (%CPU)| Time     |    TQ  |IN-OUT| PQ Distrib |      

----------------------------------------------------------------------------------------------

|   0 | SELECT STATEMENT   |    |     1 |    51   (4)| 00:00:01 |    |      |    |  

|   1 |  SORT AGGREGATE        |          |     1 |    |    |        |      |    |    

|   2 |   PX COORDINATOR       |   |       |            |          |        |    |    |            

|   3 |    PX SEND QC (RANDOM) | :TQ10000 |     1 |    |   |  Q1,00 | P->S | QC(RAND)  |         

|   4 |     SORT AGGREGATE     |          |     1 |    |  |  Q1,00 | PCWP |  |                   

|   5 |      PX BLOCK ITERATOR |          | 91791 |    51   (4)| 00:00:01 |  Q1,00 | PCWC|  |    

|   6 |       TABLE ACCESS FULL| T1       | 91791 |    51   (4)| 00:00:01 |  Q1,00 | PCWP |  |     

-----------------------------------------------------------------------------------------------

并行度越高,代价越低

SQL> alter table t1 parallel 4;

表已更改。

也可以通过使用表的属性来定义并行度,但是影响比较大,不如语句级别限制并行!

SQL> select count(*) from t1;

执行计划

-----------------------------------------------------------------------------------------

| Id  | Operation      | Name     | Rows  | Cost (%CPU)| Time   |    TQ  |IN-OUT| PQDistrib |     

---------------------------------------------------------------------------------------------

|   0 | SELECT STATEMENT   |      |     1 |    25   (0)| 00:00:01 |    |    |    |         

|   1 |  SORT AGGREGATE        |       |     1 |      |          |        |      |     |         

|   2 |   PX COORDINATOR       |          |       |        |      |        |      |    |         

|   3 |    PX SEND QC (RANDOM) | :TQ10000 |     1 |       |   |  Q1,00 | P->S | QC(RAND)  |      

|   4 |     SORT AGGREGATE     |          |     1 |      |      |  Q1,00 | PCWP |    |          

|   5 |      PX BLOCK ITERATOR |          | 91791 |    25   (0)| 00:00:01 |  Q1,00 | PCWC |   |   

|   6 |       TABLE ACCESS FULL| T1       | 91791 |    25   (0)| 00:00:01 |  Q1,00 | PCWP |   |  

---------------------------------------------------------------------------------------------

代价为25,代价比两个的又少一半!

SQL> --6.建立位图索引来避免全表扫描

SQL> create bitmap index i2 on t1(deptno);

索引已创建。

SQL> execute dbms_stats.gather_index_stats('SCOTT','I2');

PL/SQL 过程已成功完成。

SQL> select count(*) from t1;

执行计划

----------------------------------------------------------                                          

Plan hash value: 3738977131                                                                         

                                                                                                    

------------------------------------------------------------------------------                      

| Id  | Operation                     | Name | Rows  | Cost (%CPU)| Time     |                      

------------------------------------------------------------------------------                      

|   0 | SELECT STATEMENT              |      |     1 |     4   (0)| 00:00:01 |                      

|   1 |  SORT AGGREGATE               |      |     1 |            |          |                      

|   2 |   BITMAP CONVERSION COUNT     |      | 91791 |     4   (0)| 00:00:01 |                      

|   3 |    BITMAP INDEX FAST FULL SCAN| I2   |       |            |          |                      

------------------------------------------------------------------------------                      

SQL> alter index i2 parallel 4;

索引已更改。

SQL> select count(*) from t1;

执行计划

----------------------------------------------------------------------------------------

| Id  | Operation       | Name   | Rows  | Cost (%CPU)| Time   |   TQ  |IN-OUT| PQ Distrib |     

----------------------------------------------------------------------------------------------

|   0 | SELECT STATEMENT     |      |     1 |     2   (0)| 00:00:01 |      | |       |           

|   1 |  SORT AGGREGATE   |   |     1 |            |          |        |  |      |                

|   2 |   PX COORDINATOR   |      |       |       |          |        |  |    |                

|   3 |    PX SEND QC (RANDOM) | :TQ10000 |     1 |    |          |  Q1,00 | P->S | QC (RAND) |    

|   4 |     SORT AGGREGATE  |    |     1 |   |      |  Q1,00 | PCWP |        |         

|   5 |      PX BLOCK ITERATOR |  | 91791 |     2   (0)| 00:00:01 |  Q1,00 |PCWC |     |         

|   6 |       BITMAP CONVERSION COUNT  |   | 91791 |  2   (0)| 00:00:01 |  Q1,00 |PCWP |    |   

|   7 |        BITMAP INDEX FAST FULL SCAN| I2    |   |     |     |  Q1,00 | PCWP |    |         

--------------------------------------------------------------------------------------------

代价为2,原来为124,优化无止境呀!
Oracle count的优化-避免全表扫描

VPS购买请点击我

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

目录[+]