首次Oracle SQL Tuning经历
来源:互联网 发布:淘宝保证金是什么意思 编辑:程序博客网 时间:2024/05/22 01:41
这篇文章跟我一样的菜鸟可以看看。事情的缘由在上一篇Blog:如何判断程序处于I/O等待里面已经介绍过了。这件事情我也得到一个教训,QA环境和Production环境还是很不同的,特别是DB 操作,QA环境数据库数据量比较小,SQL执行计划在Production上可能得出完全不同的结果,而我的遭遇就是一条SQL在Production上一跑就再也回不来了,最后只好让DBA kill掉那个任务。
原来的SQL是这样的:一共牵涉5张表,表名和 每张表的索引情况如下:
TableIndex NameIndex InfomationTable_ItemItem_PKPRIMARY KEY (ID)Table_ItemItem_LM_IDXLast_Modified AscTable_AttrAttr_PKPRIMARY KEY (ID)Table_DescDesc_PKPRIMARY KEY (ID)Table_DelayDelay_PKPRIMARY KEY (ID, PARTITION_KEY)Table_ProductProduct_P_PKPRIMARY KEY(Product_ID)select … from , Table_Desc , Table_Product , Table_Attr , Table_Delayed
where
(Table_Item.id = Table_Desc.id)
and (Table_Item.product_id = Table_Product.product_id(+))
and (Table_Item.id = Table_Attr.id(+))
and (Table_Item.id = Table_Delay.id(+))
and (Table_Item.last_modified between to_date( :start_time, ‘YYYY-MM-DD HH24:MI:SS’ )
and to_date( :end_time , ‘YYYY-MM-DD HH24:MI:SS’ )
)
order by Table_Item.last_modified;
使用的DB Hint 是:
/*+ index(table_item item_lm_idx) use_nl(table_delay) index(table_delay delay_pk) */
SQL> explain plan for
select …
SQL> @?/rdbms/admin/utlxpls
由于打印格式不同,我就不把执行计划贴出来了,执行情况良好:
- 所有的表都使用的了索引,Index Range Scan或者Index Unique Scan
- 执行Join的时候使用了Nested Loops或者Nested Loops Outer
- 没有发现Sort Join和Merge Join
- 没有发现Table Access Full –> Full Table Scan
我们发现即使在SQL中有order by table_item.last_modified,在SQL执行计划中也没有出现任何Sort有关的信息,一般在SQL中尽量不要使用order by,因为在DB Server端进行Sort是很耗费资源的。但是有一个例外,就是表中的数据已经排好序的情况下,我们这里就是这样的哦情况,执行计划中没有Sort是因为当从Table_Item表中以 Table_Item.last_modified between :start_time and :end_time取数据时,走的是Item_LM_IDX –>Last_Modified Asc, 所以取出来的数据本身已经按照last_modified 排好序了。
但是我更改过的SQL是这样的:
where Table_Item.last_modified=:start_time and Table_Item.ID>:last_id order by Table_Item.ID
让我悲哀的是这条修改过的SQL在有些数据库服务器上的执行计划是好的,有些不好。DBA给我的解释是并不是所有的表的统计信息都是更新过的,于是在那些统计信息没有更新的表上的执行计划很有可能就不对了。不如说这个:
00 SELECT STATEMENT
01 MERGE JOIN OUTER
02 NESTED LOOPS OUTER(将Item,Product,Desc的结果和Table_Delay进行Nested Join)
03 MERGE JOIN(由两个SORT JOIN的结果组成,得到Item,Product,Desc3张表的Join结果)
04 SORT JOIN(将Table_Item和Table_Product的结果按照ID进行排序)
05 NESTED LOOPS OUTER(将Table_Item和Table_Product进行Nested Outer Join)
06 TABLE ACCESS BY INDEX ROWID –> Table_Item
07 INDEX RANGE SCAN –> Item_LM_IDX(使用Item_LM_IDX索引)
08 TABLE ACCESS BY INDEX ROWID –> Table_Product
09 INDEX UNIQUE SCAN –> Product_P_PK
10 SORT JOIN(将Table_Desc满足条件的记录按照ID进行排序)
11 TABLE ACCESS BY INDEX ROWID –> Table_Desc
12 INDEX RANGE SCAN –> RTable_DESC_PK
13 PARTITION RANGE ALL
14 TABLE ACCESS BY LOCAL INDEX ROWID –> Table_Delay
15 INDEX RANGE SCAN –> Delay_PK
16 SORT JOIN
17 TABLE ACCESS FULL –> Table_Attr
注意到使用了很多Merge Sort,而处理Table_Attr的时候更是出现了Full Table Scan,更本就不使用索引。这里说句老实话,我不知道是不是应该DBA更新统计信息,重新给相关的表更新一下统计信息,还是就赶紧改一下DB Hint把自己的事情做完就算。不过我也理解的,Ebay的数据库太大了,不是随便想做什么就行的,最后我还是选择了修改DB Hint.
Ticket resolve的结果是,修改Db Hint :
/*+
index_asc(Table_Attr ATTR_PK)
index(Table_Item Item_LM_IDX)
use_nl(Table_Item Table_Attr Table_Desc Table_Delayed Table_Product) index(Table_Delay DELAY_PK)
index(Table_Product PRODUCT_P_PK)
index(Table_Desc RTable_DESC_PK)
*/
给所有的表都制定Index,建议Oracle对所有的表都使用Nested Loops Join。重新看一下执行计划:
00 SELECT STATEMENT
01 SORT ORDER BY
02 NESTED LOOPS OUTER
03 NESTED LOOPS OUTER
…(以下省略)
可以看到,修改DB Hint以后,只有对最后的结果进行SORT,这也是我们的初衷。没有SORT JOIN和Merge Join了。速度也快了很多。因为Ebay的DB是Split的,DBA为了保险,帮我把这条修改过的SQL对该数据库所有的Splits都运行了一次,才把Ticket标识成Resolved.
我刚把代码改了,添加了判断,如果运行新的SQL就使用修改的Hint。待会给QA测试,IDC的Sunil还不肯发BUG给我,因为他在QA环境没有观察到这个问题,甚至的Production StandBy DB也不能重现。这一点只能用楼上DBA的话来解释了:虽然是同一个DB的不同的Split,但是不同的Splits之间数据还是有差异,统计数据也不同,结果是影响Oracle做出判断,所以他们做SQL Review的时候都是要运行一下的,而不是光看看执行计划。
谢谢COC DBA Team的amao和alex给我上了一课。
- 首次Oracle SQL Tuning经历
- ORACLE PERFORMANCE SQL TUNING
- oracle sql tuning
- Oracle sql statement tuning
- Oracle SQL tuning 步骤
- Oracle SQL tuning 步骤
- ORACLE SQL Performance Tuning
- Oracle SQL tuning 步骤
- Oracle SQL Tuning知识
- Oracle SQL Tuning Advisor
- Oracle SQL tuning 步骤
- Oracle SQL tuning 步骤
- Oracle SQL tuning 步骤
- Oracle SQL tuning 步骤
- Oracle SQL Tuning知识
- Oracle SQL Query Tuning Hints
- Oracle SQL Tuning Pocket Reference
- ORACLE SQL TUNING ADVISOR 使用方法
- 数据库学习笔记–Application Design and Development(2)
- Oracle 10g Express的Getting Started Hands On
- libavformat/libavcodec学习(mplayer)
- 局域网共享权限设置和指定ip设置
- 无法卸载office 2010 beta的解决方案
- 首次Oracle SQL Tuning经历
- Android sax解析XML数据
- euca-describe-availability-zones verbose shows 0 max
- MYSQL中的CREATE TEMPORARY TABLE
- Rebuild MySQL Slave Server
- android 数据库与 provider uri 之间的关系
- 如何保护.net中的dll文件(防止破解、反编译dll)
- slf4j, Simple Logging Facade for Java 的包使用说明
- C#打包应用程序(安装程序)