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会将表的总行数存储起来,定期维护,但是注意,一旦加 ...
随机推荐
- (转)RabbitMQ消息队列(九):Publisher的消息确认机制
在前面的文章中提到了queue和consumer之间的消息确认机制:通过设置ack.那么Publisher能不到知道他post的Message有没有到达queue,甚至更近一步,是否被某个Consum ...
- javascript之面向对象程序设计(对象和继承)
总结的文章略长,慎点. 知识点预热 引用类型:引用类型的值(对象)是引用类型的一个实例.在ECMAScript中,引用类型是一种数据结构,用于将数据和功能组织在一起.在其他面向对象语言中被称为类,虽然 ...
- 在windows下使用linux的开发环境
windows下做开发确实有些不方便,比如python.ruby什么的都要自己装,不过这还是小事情.有一次想安装node-sass,windows下报错缺少MSBuild什么的,可能需要装一个vs解决 ...
- 生成HTMLTestRunner测试报告的操作步骤——Python+selenium自动化
HTMLTestRunner是Python标准库的unittest模块的一个扩展,具体操作如下 1.安装 环境:Window8 步骤:1)http://tungwaiyip.info/software ...
- 在MAC系统上进行屏幕录制
最近打算将一些软件操作过程进行屏幕录制进行视频分享,所以寻思着找一块能在MAC上使用的屏幕录制软件.google了一番,没想到MAC系统自带的QuickTime Player已经内置屏幕录像功能,而且 ...
- vs2008团队资源管理器安装步骤
1.先装 VS2008TeamExplorer { NOTE: 要区分中英文版本Microsoft Visual Studio 2008 Service Pack 1 (iso) VS2008SP1C ...
- Js apply() call()使用详解
Js apply方法详解我在一开始看到javascript的函数apply和call时,非常的模糊,看也看不懂,最近在网上看到一些文章对apply方法和call的一些示例,总算是看的有点眉目了,在这里 ...
- setLayoutParams设置leftMargin后在模拟器上可以真机上不行
LinearLayout.LayoutParams lp = getLayoutParamsFromExit( (LayoutParams) this.getLayoutParams()); ...
- 22 高级SQL特性
1.约束 为正确地进行关系数据库设计,需要一种方法来保证只在表中插入合法的数据.例如,如果Orders表存储订单信息,OrderItems表存储订单详细内容,应该保证Orderitems中引用的任何订 ...
- 在Windows 上安装SQL Server的一些注意事项
基本来说安装SQL Server 单节点数据库并不是很困难的事情,大多可以通过Next来安装完成.其中要注意以下几点 安装.net3.5 可以参考本Blog的一些安装须知. Windows Serve ...