select count的优化
分类: Oracle
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,优化无止境呀!
只有你把握原理,一切尽在掌握!
select count的优化的更多相关文章
- SQL Select count(*)和Count(1)的区别和执行方式及SQL性能优化
SQL性能优化:http://www.cnblogs.com/CareySon/category/360333.html Select count(*)和Count(1)的区别和执行方式 在SQL S ...
- 从多表连接后的select count(*)看待SQL优化
从多表连接后的select count(*)看待SQL优化 一朋友问我,以下这SQL能直接改写成select count(*) from a吗? SELECT COUNT(*) FROM a LEFT ...
- SQL优化之SELECT COUNT(*)
前言 SQL优化之SQL 进阶技巧(上) SQL优化之SQL 进阶技巧(下)中提到使用以下 sql 会导致慢查询 SELECT COUNT(*) FROM SomeTable SELECT COUNT ...
- select count(*)优化 快速得到总记录数
1.select count(*) from table_name 比select count(主键列) from table_name和select count(1) from table_name ...
- Select count(*)和Count(1)的区别和执行方式
在SQL Server中Count(*)或者Count(1)或者Count([列])或许是最常用的聚合函数.很多人其实对这三者之间是区分不清的.本文会阐述这三者的作用,关系以及背后的原理. ...
- SQLSERVER 里SELECT COUNT(1) 和SELECT COUNT(*)哪个性能好?
SQLSERVER 里SELECT COUNT(1) 和SELECT COUNT(*)哪个性能好? 今天遇到某人在我以前写的一篇文章里问到 如果统计信息没来得及更新的话,那岂不是统计出来的数据时错误的 ...
- mysql技巧之select count的比较
在工作过程中,时不时会有开发咨询几种select count()的区别,我总会告诉他们使用select count(*) 就好.下文我会展示几种sql的执行计划来说明为啥是这样. 1.测试 ...
- select count(*) 底层究竟做了什么?
阅读本文大概需要 6.6 分钟. SELECT COUNT( * ) FROM t是个再常见不过的 SQL 需求了.在 MySQL 的使用规范中,我们一般使用事务引擎 InnoDB 作为(一般业务)表 ...
- mysql 查询优化 ~ select count 知多少
一 简介:今天咱们来聊聊mysql的查询总数 二 具体介绍 1 从引擎层面说 myisam myisam的扫描总行数是非常快的,这是因为myisam会将表的总行数存储起来,定期维护,但是注意,一旦加 ...
随机推荐
- trident 序列号问题
在使用Storm的trident做流计算开发时,遇到一个诡异的问题: 我继承IPartitionedTridentSpout或者IOpaquePartitionedTridentSpout接口做事务型 ...
- 3月3日 Mark
感觉LeetCode OJ 水题较多... 不过回复基础就是这样吧.. 刚刚和Gaewah聊了下,后续可以考虑去做Topcoder的SRM或者codeforces,Mark.
- 【风马一族_xml】xml的两种解析思想
xml的解析思想 dom解析 将整个xml使用类似树的结构保存在内存中,再进行对其操作 是woc组织推荐的处理xml的一种方式 需要等到xml完全加载进内存才可以进行操作 耗费内存.当解析超大的xml ...
- MySQL触发器 Update触发Insert失败
今天工作需要,想要实现将仅对状态更新的表进行历史记录显示,于是考虑在原表中建立触发器,将更新的内容同时写入另一张表 于是进行测试 --建立测试表CREATE TABLE `triggletest_tr ...
- 安装WordPress详细教程指南
最近准备自己建一个个人博客,以便分享一些自己工作生活中的一些观点及经验,建博客当然选wordpress,毕竟wordpress是为博客而生的嘛.下边记录一下自己安装WordPress的详细过程指南,亦 ...
- jquery 1.6发布后,增加prop()方法部分取代attr()方法
以前的jq中,全部使用attr来访问对象的属性,比如取一个图片的alt属性,就可以这样做$('#img').attr('alt'); 但是在某些时候,比如访问checkbox的disabled属性 ...
- WinDbg 调试.net程序
WinDbg支持以下三种类型的命令: · 常规命令,用来调试进程 · 点命令,用来控制调试器 · 扩展命令,可以添加叫WinDbg的自定义命令,一般由扩展dl ...
- 防DDOS攻击
/ip firewall filter add chain=forward connection-state=new action=jump jump-target=block-ddos add ch ...
- Global::pickSpecificClass_DNT
/*************************************************** Created Date: 13 Jul 2013 Created By: Jimmy Xie ...
- mootools和jquery冲突的解决
mootools-jquery 今天在做EcStore前台的做效果时,由于Jquery的插件比较多,于是就使用了Jquery的插件,但是发现会引起Mootools的冲突. 于是猛找资料,终于找到了,现 ...