一次SQL优化分析的全过程

转载 2004年07月15日 11:26:00

作者介绍:
盖国强,曾任ITPUB MS 版版主,现任Oracle 数据库管理版版主。曾任职于某国家大
型企业,服务于烟草行业,开发过基于Oracle 数据库的大型ERP 系统,属国家信息产业部
重点工程。同时负责Oracle 数据库管理及优化,并为多家烟草企业提供Oracle 数据库管理、
优化及技术支持。目前任职于北京某电信增值业务系统提供商企业,负责数据库业务。管
理全国30 多个省点数据库平台。实践经验丰富,长于数据库诊断、优化与SQL 调整。希
望与大家共同学习提高Oracle 技术水平。
Mail: eygle@itpub.net
以下是一次SQL 优化分析的全过程,曾经在itpub 上发过相关的帖子,现在整理了一
下,添加了详细的说明,希望对大家有些帮助。
环境说明:
数据库版本:Oracle8.1.7.4
平台:Hp-Ux11i
以下是从程序员处获得的一段代码,开发人员抱怨这段代码执行缓慢,我执行该段代码
获得执行计划,分析如下:
这是该段代码的执行计划及统计数据:
SQL> SELECT "SP_TRANS"."TRANS_NO",
2 "SP_TRANS_SUB"."ITEM_CODE",
3 "SP_ITEM"."ITEM_NAME",
4 "SP_ITEM"."CHART_ID",
5 "SP_ITEM"."SPECIFICATION",
6 "SP_TRANS_SUB"."COUNTRY",
7 "SP_TRANS_SUB"."QTY",
8 "SP_TRANS_SUB"."PRICE",
9 "SP_TRANS"."VENDOR_CODE",
10 "SP_TRANS"."PAY_MODE",
11 NVL("SP_TRANS_SUB"."PAY_QTY",0),
12 0 as PAY_THIS
13 FROM "SP_ITEM",
14 "SP_TRANS_SUB",
15 "SP_TRANS"
16 WHERE ( "SP_TRANS_SUB"."TRANS_NO" = "SP_TRANS"."TRANS_NO" ) and
17 ( "SP_ITEM"."ITEM_CODE" = "SP_TRANS_SUB"."ITEM_CODE" ) and
18 ( ( "SP_TRANS"."VENDOR_CODE" = '20011021023') )
19 /
8 rows selected.
Elapsed: 00: 00: 00.51
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE
1 0 NESTED LOOPS
2 1 NESTED LOOPS
3 2 TABLE ACCESS (FULL) OF 'SP_TRANS'
4 2 TABLE ACCESS (BY INDEX ROWID) OF 'SP_TRANS_SUB'
5 4 INDEX (RANGE SCAN) OF 'PK_SP_TRANS_SUB' (UNIQUE)
6 1 TABLE ACCESS (BY INDEX ROWID) OF 'SP_ITEM'
7 6 INDEX (UNIQUE SCAN) OF 'PK_SP_ITEM' (UNIQUE)
Statistics
----------------------------------------------------------
0 recursive calls
4 db block gets
323 consistent gets
0 physical reads
0 redo size
1809 bytes sent via SQL*Net to client
425 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
8 rows processed
该段代码用以按供货商查询2003 年开始的处理单据(当时的数据量很少),查询时间大
约是0.51 秒。
此前这几个表都没有分析过,数据库选择的是RBO 优化器。
为了加快代码的执行,analyze 相关表:
SQL> analyze table sp_trans_sub compute statistics;
Table analyzed.
Elapsed: 00: 00: 30.64
SQL> SELECT "SP_TRANS"."TRANS_NO",
2 "SP_TRANS_SUB"."ITEM_CODE",
3 "SP_ITEM"."ITEM_NAME",
4 "SP_ITEM"."CHART_ID",
5 "SP_ITEM"."SPECIFICATION",
6 "SP_TRANS_SUB"."COUNTRY",
7 "SP_TRANS_SUB"."QTY",
8 "SP_TRANS_SUB"."PRICE",
9 "SP_TRANS"."VENDOR_CODE",
10 "SP_TRANS"."PAY_MODE",
11 NVL("SP_TRANS_SUB"."PAY_QTY",0),
12 0 as PAY_THIS
13 FROM "SP_ITEM",
14 "SP_TRANS_SUB",
15 "SP_TRANS"
16 WHERE ( "SP_TRANS_SUB"."TRANS_NO" = "SP_TRANS"."TRANS_NO" ) and
17 ( "SP_ITEM"."ITEM_CODE" = "SP_TRANS_SUB"."ITEM_CODE" ) and
18 ( ( "SP_TRANS"."VENDOR_CODE" = '20011021023') )
19 /
8 rows selected.
Elapsed: 00: 00: 06.49
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=18577 Card=126726520
Bytes=30034185240)
1 0 MERGE JOIN (Cost=18577 Card=126726520 Bytes=30034185240)
2 1 SORT (JOIN) (Cost=14722 Card=310300 Bytes=20790100)
3 2 HASH JOIN (Cost=358 Card=310300 Bytes=20790100)
4 3 TABLE ACCESS (FULL) OF 'SP_TRANS' (Cost=43 Card=229 Bytes=8473)
5 3 TABLE ACCESS (FULL) OF 'SP_TRANS_SUB' (Cost=158 Card =135502 Bytes=4065060)
6 1 SORT (JOIN) (Cost=3855 Card=40840 Bytes=6942800)
7 6 TABLE ACCESS (FULL) OF 'SP_ITEM' (Cost=77 Card=40840 Bytes=6942800)
Statistics
----------------------------------------------------------
150 recursive calls
89 db block gets
1837 consistent gets
755 physical reads
60 redo size
1732 bytes sent via SQL*Net to client
425 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
4 sorts (memory)
1 sorts (disk)
8 rows processed
SQL>
SQL> analyze table sp_trans compute statistics;
Table analyzed.
Elapsed: 00: 00: 13.00
SQL>
SQL> SELECT "SP_TRANS"."TRANS_NO",
2 "SP_TRANS_SUB"."ITEM_CODE",
3 "SP_ITEM"."ITEM_NAME",
4 "SP_ITEM"."CHART_ID",
5 "SP_ITEM"."SPECIFICATION",
6 "SP_TRANS_SUB"."COUNTRY",
7 "SP_TRANS_SUB"."QTY",
8 "SP_TRANS_SUB"."PRICE",
9 "SP_TRANS"."VENDOR_CODE",
10 "SP_TRANS"."PAY_MODE",
11 NVL("SP_TRANS_SUB"."PAY_QTY",0),
12 0 as PAY_THIS
13 FROM "SP_ITEM",
14 "SP_TRANS_SUB",
15 "SP_TRANS"
16 WHERE ( "SP_TRANS_SUB"."TRANS_NO" = "SP_TRANS"."TRANS_NO" ) and
17 ( "SP_ITEM"."ITEM_CODE" = "SP_TRANS_SUB"."ITEM_CODE" ) and
18 ( ( "SP_TRANS"."VENDOR_CODE" = '20011021023') )
19 /
8 rows selected.
Elapsed: 00: 00: 01.62
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=1453 Card=447198 Bytes=101066748)
1 0 NESTED LOOPS (Cost=1453 Card=447198 Bytes=101066748)
2 1 HASH JOIN (Cost=358 Card=1095 Bytes=61320)
3 2 TABLE ACCESS (FULL) OF 'SP_TRANS' (Cost=43 Card=273 Bytes=7098)
4 2 TABLE ACCESS (FULL) OF 'SP_TRANS_SUB' (Cost=158 Card=135502 Bytes=4065060)
5 1 TABLE ACCESS (BY INDEX ROWID) OF 'SP_ITEM' (Cost=1 Card= 40840 Bytes=6942800)
6 5 INDEX (UNIQUE SCAN) OF 'PK_SP_ITEM' (UNIQUE)
Statistics
----------------------------------------------------------
0 recursive calls
8 db block gets
1344 consistent gets
0 physical reads
0 redo size
1824 bytes sent via SQL*Net to client
425 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
3 sorts (memory)
0 sorts (disk)
8 rows processed
SQL>
SQL> analyze table sp_item compute statistics
2 /
Table analyzed.
Elapsed: 00: 00: 11.67
SQL> SELECT "SP_TRANS"."TRANS_NO",
2 "SP_TRANS_SUB"."ITEM_CODE",
3 "SP_ITEM"."ITEM_NAME",
4 "SP_ITEM"."CHART_ID",
5 "SP_ITEM"."SPECIFICATION",
6 "SP_TRANS_SUB"."COUNTRY",
7 "SP_TRANS_SUB"."QTY",
8 "SP_TRANS_SUB"."PRICE",
9 "SP_TRANS"."VENDOR_CODE",
10 "SP_TRANS"."PAY_MODE",
11 NVL("SP_TRANS_SUB"."PAY_QTY",0),
12 0 as PAY_THIS
13 FROM "SP_ITEM",
14 "SP_TRANS_SUB",
15 "SP_TRANS"
16 WHERE ( "SP_TRANS_SUB"."TRANS_NO" = "SP_TRANS"."TRANS_NO" ) and
17 ( "SP_ITEM"."ITEM_CODE" = "SP_TRANS_SUB"."ITEM_CODE" ) and
18 ( ( "SP_TRANS"."VENDOR_CODE" = '20011021023') )
19 /
8 rows selected.
Elapsed: 00: 00: 01.43
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=687 Card=1362 Bytes=128028)
1 0 HASH JOIN (Cost=687 Card=1362 Bytes=128028)
2 1 HASH JOIN (Cost=358 Card=1362 Bytes=76272)
3 2 TABLE ACCESS (FULL) OF 'SP_TRANS' (Cost=43 Card=273 Bytes=7098)
4 2 TABLE ACCESS (FULL) OF 'SP_TRANS_SUB' (Cost=158 Card=135502 Bytes=4065060)
5 1 TABLE ACCESS (FULL) OF 'SP_ITEM' (Cost=77 Card=29547 Bytes=1122786)
Statistics
----------------------------------------------------------
0 recursive calls
12 db block gets
1820 consistent gets
0 physical reads
0 redo size
1732 bytes sent via SQL*Net to client
425 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
3 sorts (memory)
0 sorts (disk)
8 rows processed
当分析了所有表以后,我们发现,最后Oracle 给我选择了三个全表扫描。而且,从db
block gets 、consistent gets 全都“提高”了。
然后我在VENDOR_CODE 列上建了一个索引,试图通过索引加快代码的执行(在实际应用
中,通过添加适当的索引来加快SQL 执行是常用的方法,尤其是在RBO 模式下,但是添加索
引可能改变很多相关SQL 的执行计划,是否获得确切的性能提高,需要进行相应的测试来验
证,Oracle9i 提供索引监视的功能,你可以通过ALTER INDEX .. MONITORING USAGE 语句
来收集索引的使用信息,以确认索引是否被正常使用):
SQL> create index idx_vendor on sp_trans(vendor_code);
索引已创建。
已用时间: 00: 00: 02.03
SQL> SELECT "SP_TRANS"."TRANS_NO",
2 "SP_TRANS_SUB"."ITEM_CODE",
3 "SP_ITEM"."ITEM_NAME",
4 "SP_ITEM"."CHART_ID",
5 "SP_ITEM"."SPECIFICATION",
6 "SP_TRANS_SUB"."COUNTRY",
7 "SP_TRANS_SUB"."QTY",
8 "SP_TRANS_SUB"."PRICE",
9 "SP_TRANS"."VENDOR_CODE",
10 "SP_TRANS"."PAY_MODE",
11 NVL("SP_TRANS_SUB"."PAY_QTY",0),
12 0 as PAY_THIS
13 FROM "SP_ITEM",
14 "SP_TRANS_SUB",
15 "SP_TRANS"
16 WHERE ( "SP_TRANS_SUB"."TRANS_NO" = "SP_TRANS"."TRANS_NO" ) and
17 ( "SP_ITEM"."ITEM_CODE" = "SP_TRANS_SUB"."ITEM_CODE" ) and
18 ( ( "SP_TRANS"."VENDOR_CODE" = '20011021023') )
19 /
已选择8 行。
已用时间: 00: 00: 01.42
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=646 Card=1362 Bytes= 128028)
1 0 HASH JOIN (Cost=646 Card=1362 Bytes=128028)
2 1 HASH JOIN (Cost=317 Card=1362 Bytes=76272)
3 2 TABLE ACCESS (BY INDEX ROWID) OF 'SP_TRANS' (Cost=2 Card=273 Bytes=7098)
4 3 INDEX (RANGE SCAN) OF 'IDX_VENDOR' (NON-UNIQUE) (Cost=1 Card=273)
5 2 TABLE ACCESS (FULL) OF 'SP_TRANS_SUB' (Cost=158 Card=135502 Bytes=4065060)
6 1 TABLE ACCESS (FULL) OF 'SP_ITEM' (Cost=77 Card=29547 Bytes=1122786)
Statistics
----------------------------------------------------------
0 recursive calls
8 db block gets
1546 consistent gets
1 physical reads
0 redo size
1732 bytes sent via SQL*Net to client
425 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
3 sorts (memory)
0 sorts (disk)
8 rows processed
SQL>
现在数据库使用了这个索引,执行计划稍好了一点,可是效果仍然不让人满意。
然后我删后来创建的索引,添加Rule 提示,这是我们得到了最初的执行计划
SQL> SELECT /*+ rule */ "SP_TRANS"."TRANS_NO",
2 "SP_TRANS_SUB"."ITEM_CODE",
3 "SP_ITEM"."ITEM_NAME",
4 "SP_ITEM"."CHART_ID",
5 "SP_ITEM"."SPECIFICATION",
6 "SP_TRANS_SUB"."COUNTRY",
7 "SP_TRANS_SUB"."QTY",
8 "SP_TRANS_SUB"."PRICE",
9 "SP_TRANS"."VENDOR_CODE",
10 "SP_TRANS"."PAY_MODE",
11 NVL("SP_TRANS_SUB"."PAY_QTY",0),
12 0 as PAY_THIS
13 FROM "SP_ITEM",
14 "SP_TRANS_SUB",
15 "SP_TRANS"
16 WHERE ( "SP_TRANS_SUB"."TRANS_NO" = "SP_TRANS"."TRANS_NO" ) and
17 ( "SP_ITEM"."ITEM_CODE" = "SP_TRANS_SUB"."ITEM_CODE" ) and
18 ( ( "SP_TRANS"."VENDOR_CODE" = '20011021023') )
19 /
已选择8 行。
已用时间: 00: 00: 00.71
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=HINT: RULE
1 0 NESTED LOOPS
2 1 NESTED LOOPS
3 2 TABLE ACCESS (FULL) OF 'SP_TRANS'
4 2 TABLE ACCESS (BY INDEX ROWID) OF 'SP_TRANS_SUB'
5 4 INDEX (RANGE SCAN) OF 'PK_SP_TRANS_SUB' (UNIQUE)
6 1 TABLE ACCESS (BY INDEX ROWID) OF 'SP_ITEM'
7 6 INDEX (UNIQUE SCAN) OF 'PK_SP_ITEM' (UNIQUE)
Statistics
----------------------------------------------------------
0 recursive calls
4 db block gets
323 consistent gets
0 physical reads
0 redo size
1809 bytes sent via SQL*Net to client
426 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
8 rows processed
SQL>
然后我们再次创建这个索引,得出的时间大大缩短(为存在性能问题的数据库查询添加
必要的索引,是DBA 解决问题的重要手段之一):
SQL> create index idx_vendor on sp_trans(vendor_code);
索引已创建。
已用时间: 00: 00: 02.43
SQL> SELECT /*+ rule */ "SP_TRANS"."TRANS_NO",
2 "SP_TRANS_SUB"."ITEM_CODE",
3 "SP_ITEM"."ITEM_NAME",
4 "SP_ITEM"."CHART_ID",
5 "SP_ITEM"."SPECIFICATION",
6 "SP_TRANS_SUB"."COUNTRY",
7 "SP_TRANS_SUB"."QTY",
8 "SP_TRANS_SUB"."PRICE",
9 "SP_TRANS"."VENDOR_CODE",
10 "SP_TRANS"."PAY_MODE",
11 NVL("SP_TRANS_SUB"."PAY_QTY",0),
12 0 as PAY_THIS
13 FROM "SP_ITEM",
14 "SP_TRANS_SUB",
15 "SP_TRANS"
16 WHERE ( "SP_TRANS_SUB"."TRANS_NO" = "SP_TRANS"."TRANS_NO" ) and
17 ( "SP_ITEM"."ITEM_CODE" = "SP_TRANS_SUB"."ITEM_CODE" ) and
18 ( ( "SP_TRANS"."VENDOR_CODE" = '20011021023') )
19 /
已选择8 行。
已用时间: 00: 00: 00.31
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=HINT: RULE
1 0 NESTED LOOPS
2 1 NESTED LOOPS
3 2 TABLE ACCESS (BY INDEX ROWID) OF 'SP_TRANS'
4 3 INDEX (RANGE SCAN) OF 'IDX_VENDOR' (NON-UNIQUE)
5 2 TABLE ACCESS (BY INDEX ROWID) OF 'SP_TRANS_SUB'
6 5 INDEX (RANGE SCAN) OF 'PK_SP_TRANS_SUB' (UNIQUE)
7 1 TABLE ACCESS (BY INDEX ROWID) OF 'SP_ITEM'
8 7 INDEX (UNIQUE SCAN) OF 'PK_SP_ITEM' (UNIQUE)
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
49 consistent gets
1 physical reads
0 redo size
1809 bytes sent via SQL*Net to client
426 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
8 rows processed
SQL>
然而这不是最快的,这是RBO
我们修改optimizer_index_cost_adj 这个初始化参数,然后再来查看该SQL 的执行计
划。
SQL> alter session set optimizer_index_cost_adj=30
2 /
会话已更改。
已用时间: 00: 00: 00.20
SQL> SELECT "SP_TRANS"."TRANS_NO",
2 "SP_TRANS_SUB"."ITEM_CODE",
3 "SP_ITEM"."ITEM_NAME",
4 "SP_ITEM"."CHART_ID",
5 "SP_ITEM"."SPECIFICATION",
6 "SP_TRANS_SUB"."COUNTRY",
7 "SP_TRANS_SUB"."QTY",
8 "SP_TRANS_SUB"."PRICE",
9 "SP_TRANS"."VENDOR_CODE",
10 "SP_TRANS"."PAY_MODE",
11 NVL("SP_TRANS_SUB"."PAY_QTY",0),
12 0 as PAY_THIS
13 FROM "SP_TRANS",
14 "SP_ITEM",
15 "SP_TRANS_SUB"
16 WHERE ( "SP_TRANS_SUB"."TRANS_NO" = "SP_TRANS"."TRANS_NO" ) and
17 ( "SP_ITEM"."ITEM_CODE" = "SP_TRANS_SUB"."ITEM_CODE" ) and
18 ( ( "SP_TRANS"."VENDOR_CODE" = '20011021023') )
19 /
已选择8 行。
已用时间: 00: 00: 00.11
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=658 Card=1095 Bytes= 102930)
1 0 NESTED LOOPS (Cost=658 Card=1095 Bytes=102930)
2 1 NESTED LOOPS (Cost=329 Card=1095 Bytes=61320)
3 2 TABLE ACCESS (BY INDEX ROWID) OF 'SP_TRANS' (Cost=1 Card=273 Bytes=7098)
4 3 INDEX (RANGE SCAN) OF 'IDX_VENDOR' (NON-UNIQUE) (Cost=1 Card=273)
5 2 TABLE ACCESS (BY INDEX ROWID) OF 'SP_TRANS_SUB' (Cost= 2 Card=135502
Bytes=4065060)
6 5 INDEX (RANGE SCAN) OF 'PK_SP_TRANS_SUB' (UNIQUE) (Cost=3 Card=135502)
7 1 TABLE ACCESS (BY INDEX ROWID) OF 'SP_ITEM' (Cost=1 Card=29547 Bytes=1122786)
8 7 INDEX (UNIQUE SCAN) OF 'PK_SP_ITEM' (UNIQUE)
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
49 consistent gets
0 physical reads
0 redo size
1809 bytes sent via SQL*Net to client
426 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
8 rows processed
SQL>
我们来看看以下两个参数对于CBO 的巨大影响:
OPTIMIZER_INDEX_CACHING
这个初始化参数代表一个百分比,取值范围在0 到99 之间.
缺省值是0,代表当CBO 使用索引访问数据时,在内存中发现数据的比率是0%,这
意味着通过索引访问数据将需要产生物理读取,代价昂贵。如果使用缺省设置,Oracle
评估成本的时候,很多时候就会错误的选择全表扫描。
OPTIMIZER_INDEX_COST_ADJ
这个初始化参数代表一个百分比,取值范围在1 到10000 之间.
该参数表示索引扫描和全表扫描成本的表较。缺省值100 表示索引扫描成本等于全
表扫描。
这些参数对于CBO 的执行具有重大影响,其缺省值对于数据库来说通常需要调整。
一般来说对于OPTIMIZER_INDEX_CACHING 可以设置为90 左右
对于大多数OLTP 系统,OPTIMIZER_INDEX_COST_ADJ 可以设置在10 到50 之间。对于数
据仓库和DSS 系统,可能不能简单的把OPTIMIZER_INDEX_COST_ADJ 设置为50,通常我
们需要反复调整取得一个合理值.
SQL> drop index idx_vendor;
索引已丢弃。
已用时间: 00: 00: 00.61
SQL> /
已选择8 行。
已用时间: 00: 00: 00.11
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=700 Card=1095 Bytes= 102930)
1 0 NESTED LOOPS (Cost=700 Card=1095 Bytes=102930)
2 1 NESTED LOOPS (Cost=371 Card=1095 Bytes=61320)
3 2 TABLE ACCESS (FULL) OF 'SP_TRANS' (Cost=43 Card=273 Bytes=7098)
4 2 TABLE ACCESS (BY INDEX ROWID) OF 'SP_TRANS_SUB' (Cost= 2 Card=135502
Bytes=4065060)
5 4 INDEX (RANGE SCAN) OF 'PK_SP_TRANS_SUB' (UNIQUE) (Cost=3 Card=135502)
6 1 TABLE ACCESS (BY INDEX ROWID) OF 'SP_ITEM' (Cost=1 Card= 29547 Bytes=1122786)
7 6 INDEX (UNIQUE SCAN) OF 'PK_SP_ITEM' (UNIQUE)
Statistics
----------------------------------------------------------
0 recursive calls
4 db block gets
323 consistent gets
0 physical reads
0 redo size
1809 bytes sent via SQL*Net to client
426 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
8 rows processed
SQL>
相关文档:
以下文档都是相当好的阅读材料,有兴趣的可以仔细阅读:
关于optimizer_index_cost_adj 等影响CBO 的参数及设置:
http://www.evdbt.com/SearchIntelligenceCBO.doc
关于成本的计算等,请参考以下文章:
http://www.centrexcc.com/A%20Look%20under%20the%20Hood%20of%20CBO%20-%20the%201
0053%20Event.pdf
http://www.centrexcc.com/A%20Look%20under%20the%20Hood%20of%20CBO%20-%20the%201
0053%20Event.ppt
关于CBO,请参考以下文档:
http://metalink.oracle.com/metalink/plsql/ml2_documents.showDocument?p_database
_id=NOT&p_id=35934.1
http://www.itpub.net/showthread.php?threadid=88905
关于执行计划的设置,请参考:
http://osi.oracle.com/~tkyte/article1/autotrace.html

【MySQL】基于MySQL的SQL优化(一)——从用explain关键字分析SQL语句开始

explain显示了MySQL如何使用索引来处理select语句以及连接表。可以帮助选择更好的索引和写出更优化的查询语句。 如图:![这里写图片描述](http://img.blog.csdn....
  • tanglei6636
  • tanglei6636
  • 2016年10月17日 21:23
  • 1253

使用PL/SQL执行计划进行sql调优

使用PL/SQL执行计划进行sql调优 1、打开工具:pl/sql  developer 在pl/sql中写好一个SQL语句,然后按F5打开执行计划分析窗口 2、查看cost,获得消耗资源的总体印象 ...
  • heshouyou
  • heshouyou
  • 2017年03月07日 11:11
  • 1222

【MySql性能优化二】利用explain进行查询和分析sql语句

在mysql数据库中为我们提供了explain方法可以通过它来帮助我们分析我们的sql语句。 登录mysql后,具体使用如下这里的了例子都以上篇博客中安装的实例数据库sakila为例: explain...
  • wangyy130
  • wangyy130
  • 2016年05月16日 11:38
  • 2161

Mybatis实现【4】-查询解析(一次SQL查询的源码分析)

执行流程图:   一、在Service层调用Mapper Interface中的方法实现对数据库的操作 二、MapperProxy将拦截所有调用数据库的操作,所以实际上调用的是MapperPro...
  • timchen6824
  • timchen6824
  • 2014年06月18日 16:29
  • 3022

mysql执行sql语句优化分析命令explain命令小记

explain是用来分析sql语句,帮助优化的一个命令。她可以很详细的告诉你的sql语名出现的问题所在,以及是否用到索引。真的很好用。大家必须要会用哦! explain的语法如下:   SQL Co...
  • andyzhaojianhui
  • andyzhaojianhui
  • 2015年09月25日 00:01
  • 692

通过分析SQL语句的执行计划优化SQL (四)

第4章 ORACLE的优化器        优化器有时也被称为查询优化器,这是因为查询是影响数据库性能最主要的部分,不要以为只有SELECT语句是查询。实际上,带有任何WHERE条件的DML(INSE...
  • mustbelove
  • mustbelove
  • 2006年11月20日 17:29
  • 678

常用优化sql语句执行效率的方法

项目中优化sql语句执行效率的方法: 1)尽量选择较小的列 2)将where中用的比较频繁的字段建立索引 3)select子句中避免使用‘*’ 4)避免在索引列上使用计算、not in 和 ...
  • u011341352
  • u011341352
  • 2015年10月24日 21:40
  • 1745

网络请求全过程及其优化空间

一、网络请求全过程总览 从用户输入URL到网页呈现给用户都经过了哪些主要过程?主要有八大过程: 移动网络连接(移动端特有)DNS解析IP寻址TCP连接Request服务器处理Response页面渲...
  • chen093006
  • chen093006
  • 2017年01月12日 16:43
  • 432

数据库执行过程

1、from子句组装来自不同数据源的数据; 2、where子句基于指定的条件对记录行进行筛选; 3、group by子句将数据划分为多个分组; 4、使用聚集函数进行计算; 5、使用having...
  • liushengjop
  • liushengjop
  • 2012年05月17日 09:54
  • 99

SQL调优简介及调优方式

在日常工作或交流中,经常会讨论一些关于sql调优的问题,然后总结了下,下面我们主要是从软件方面进行分析,希望对你有帮助:         引导语:我曾有一种感觉,不管何种调优方式,索引是最根本的方法,...
  • u011463470
  • u011463470
  • 2016年03月30日 17:02
  • 3062
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:一次SQL优化分析的全过程
举报原因:
原因补充:

(最多只允许输入30个字)