源码-数据库调优(tuning)初接触
2016-10-11 00:17
162 查看
数据库调优对我而言一直是比较高深的内容,今晚看了慕课网的一节视频课程后,有点领悟了。
问题:使用分组子句的情况下,如果要过滤查询结果,而where/having都能使用(即,过滤条件不含分组函数),请问用where好还是having好?
答案:使用where子句可以获得更好的性能,因为where是“先过滤,再分组”,而having是“先分组,再过滤”。
口说无凭,以下源码为证:
scott_pd@ORCL> ed
已写入 file afiedt.buf
1* select deptno, avg(sal) from emp where deptno=10group by deptno
scott_pd@ORCL> /
DEPTNO AVG(SAL)
---------- ----------
10 5000
执行计划
----------------------------------------------------------
Plan hash value: 2854459865
-----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 6 | 3 (0)| 00:00:01 |
| 1 | SORT GROUP BY NOSORT| | 1 | 6 | 3 (0)| 00:00:01 |
|* 2 | TABLE ACCESS FULL | EMP | 9 | 54 | 3 (0)| 00:00:01 |
-----------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter("DEPTNO"=10)
统计信息
----------------------------------------------------------
0 recursive calls
0 db block gets
7 consistent gets
0 physical reads
0 redo size
605 bytes sent via SQL*Net to client
524 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
scott_pd@ORCL> ed
已写入 file afiedt.buf
1* select deptno, avg(sal) from emp group by deptno having deptno=10
scott_pd@ORCL> /
DEPTNO AVG(SAL)
---------- ----------
10 5000
执行计划
----------------------------------------------------------
Plan hash value: 2138686577
----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 6 | 4 (25)| 00:00:01 |
|* 1 | FILTER | | | | | |
| 2 | HASH GROUP BY | | 1 | 6 | 4 (25)| 00:00:01 |
| 3 | TABLE ACCESS FULL| EMP | 38 | 228 | 3 (0)| 00:00:01 |
----------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("DEPTNO"=10)
统计信息
----------------------------------------------------------
1 recursive calls
0 db block gets
7 consistent gets
0 physical reads
0 redo size
605 bytes sent via SQL*Net to client
524 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
scott_pd@ORCL> spool
当前正假脱机至 d:/20161010_group_by_tuning.txt
scott_pd@ORCL> spool out
在源码(SQL运行记录)中,我们能看到,使用where子句,共占用了9(3+3+3)个CPU单位,而having子句占用了共11(4+4+3)个CPU单位。
在数据量很庞大的情况下,两者的差距想必也很大。
懂得了这个道理,以后,在写SQL语句的时候,就可以优先使用where了。姑且将本次学习经验称之为数据库调优初接触吧。
问题:使用分组子句的情况下,如果要过滤查询结果,而where/having都能使用(即,过滤条件不含分组函数),请问用where好还是having好?
答案:使用where子句可以获得更好的性能,因为where是“先过滤,再分组”,而having是“先分组,再过滤”。
口说无凭,以下源码为证:
scott_pd@ORCL> ed
已写入 file afiedt.buf
1* select deptno, avg(sal) from emp where deptno=10group by deptno
scott_pd@ORCL> /
DEPTNO AVG(SAL)
---------- ----------
10 5000
执行计划
----------------------------------------------------------
Plan hash value: 2854459865
-----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 6 | 3 (0)| 00:00:01 |
| 1 | SORT GROUP BY NOSORT| | 1 | 6 | 3 (0)| 00:00:01 |
|* 2 | TABLE ACCESS FULL | EMP | 9 | 54 | 3 (0)| 00:00:01 |
-----------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter("DEPTNO"=10)
统计信息
----------------------------------------------------------
0 recursive calls
0 db block gets
7 consistent gets
0 physical reads
0 redo size
605 bytes sent via SQL*Net to client
524 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
scott_pd@ORCL> ed
已写入 file afiedt.buf
1* select deptno, avg(sal) from emp group by deptno having deptno=10
scott_pd@ORCL> /
DEPTNO AVG(SAL)
---------- ----------
10 5000
执行计划
----------------------------------------------------------
Plan hash value: 2138686577
----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 6 | 4 (25)| 00:00:01 |
|* 1 | FILTER | | | | | |
| 2 | HASH GROUP BY | | 1 | 6 | 4 (25)| 00:00:01 |
| 3 | TABLE ACCESS FULL| EMP | 38 | 228 | 3 (0)| 00:00:01 |
----------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("DEPTNO"=10)
统计信息
----------------------------------------------------------
1 recursive calls
0 db block gets
7 consistent gets
0 physical reads
0 redo size
605 bytes sent via SQL*Net to client
524 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
scott_pd@ORCL> spool
当前正假脱机至 d:/20161010_group_by_tuning.txt
scott_pd@ORCL> spool out
在源码(SQL运行记录)中,我们能看到,使用where子句,共占用了9(3+3+3)个CPU单位,而having子句占用了共11(4+4+3)个CPU单位。
在数据量很庞大的情况下,两者的差距想必也很大。
懂得了这个道理,以后,在写SQL语句的时候,就可以优先使用where了。姑且将本次学习经验称之为数据库调优初接触吧。
相关文章推荐
- ADO第一次亲密接触(转贴,内容主要是利用ADO连接数据库的方法)
- 连接数据库的ASP树图生成程序(源码)
- DotText源码阅读(2)-工程、数据库表结构
- 经典数据库分组查询代码(附源码)
- C#中用SqlDataAdapter修改数据库中的表(源码+注意的细节)
- 把文件以二进制格式或base64字符串形式保存到数据库中,并实现下载功能源码
- 开放源码的嵌入式数据库Berkeley DB 概述
- C#源码 备份和恢复数据库
- ASP.NET中treeview与数据库绑定的方法与相关源码
- 无组件上传图片到数据库源码
- 第一次接触 SharpHsql(纯C#开源数据库引擎)
- 采用泛型链接多类型数据库[含源码]
- 开放源码嵌入式数据库 SQLite 简介
- [转] 开放源码嵌入式数据库 SQLite 简介
- jdk1.4的logging的数据库handler实现源码
- JBPM源码分析(一)---数据库表主键ID的产生机制
- 缩小数据库日志的工具源码
- JSP连接操作数据库全接触(所有流行数据库)
- Web C#2.0 DataSet和Reader封装组件实现自动多数据库切换(含组件源码和实例)
- DB2/Informix 和开放源码:数据库防御