根据addm建议,这个sql从昨天晚上20点到现在14点执行了65390次,平均消耗了0.12S,
如果优化好这条sql,DB将得到61%的好处,不知道ORACLE是怎么计算的?
RECOMMENDATION 1: SQL Tuning, 61% benefit (8274 seconds)
ACTION: Run SQL Tuning Advisor on the SQL statement with SQL_ID
"7g98ktr8drf47".
RELEVANT OBJECT: SQL statement with SQL_ID 7g98ktr8drf47 and
PLAN_HASH 2414031861
SELECT * FROM (SELECT AA.*, ROWNUM RN FROM ( select * from
DBBS_RELY Where TOPICID = :1 order by RELYTIME asc,id asc ) AA
WHERE ROWNUM <= :2) WHERE RN >= :3
RATIONALE: SQL statement with SQL_ID "7g98ktr8drf47" was executed 65390
times and had an average elapsed time of 0.12 seconds.
我们使用DBMS_SQLTUNE看下Oracle对此条sql的建议
sys@g> /
REPORT
--------------------------------------------------------------------------------
GENERAL INFORMATION SECTION
-------------------------------------------------------------------------------
Tuning Task Name : 7g98ktr8drf47
Tuning Task Owner : SYS
Scope : COMPREHENSIVE
Time Limit(seconds) : 60
Completion Status : COMPLETED
Started at : 05/23/2012 14:23:32
Completed at : 05/23/2012 14:23:32
------------------------------------------------------------------------------
Schema Name: CYOUBBS
SQL ID : 9yqsy97khtm61
SQL Text : SELECT * FROM (SELECT AA.*, ROWNUM RN FROM ( select * from
DBBS_RELY Where TOPICID = :1 order by RELYTIME asc,id asc )
AA WHERE ROWNUM <= :2) WHERE RN >= :3
-------------------------------------------------------------------------------
ADDITIONAL INFORMATION SECTION
-------------------------------------------------------------------------------
- The optimizer could not merge the view at line ID 3 of the execution plan.
The optimizer cannot merge a view that contains an "ORDER BY" clause unless
the statement is a "DELETE" or an "UPDATE" and the parent query is the top
most query in the statement.
- The optimizer could not merge the view at line ID 1 of the execution plan.
The optimizer cannot merge a view that contains a "ROWNUM" pseudo column.
-------------------------------------------------------------------------------
EXPLAIN PLANS SECTION
-------------------------------------------------------------------------------
1- Original
-----------
Execution Plan
----------------------------------------------------------
Plan hash value: 2414031861
----------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 40 | 134K| 1160 (1)| 00:00:14 |
|* 1 | VIEW | | 40 | 134K| 1160 (1)| 00:00:14 |
|* 2 | COUNT STOPKEY | | | | | |
| 3 | VIEW | | 2626 | 8814K| 1160 (1)| 00:00:14 |
|* 4 | SORT ORDER BY STOPKEY | | 2626 | 418K| 1160 (1)| 00:00:14 |
| 5 | TABLE ACCESS BY INDEX ROWID| DBBS_RELY | 2626 | 418K| 1159 (1)| 00:00:14 |
|* 6 | INDEX RANGE SCAN | IDX_DBBS_RELY_TOPICID | 2626 | | 11 (0)| 00:00:01 |
----------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("RN">=TO_NUMBER(:3))
2 - filter(ROWNUM<=TO_NUMBER(:2))
4 - filter(ROWNUM<=TO_NUMBER(:2))
6 - access("TOPICID"=:1)
-------------------------------------------------------------------------------
在此Oracle并没有给发解决方案,只是将一些附加信息给列出来了,没什么用外,也可以看到执行计划,也都走索引了,那如何优化呢?
解决此条sql,可以从执行计划中的SORT ORDER BY STOPKEY入手,减少排序操作将会大大降低成本
2.1看下此表上那些是谓词(利用了下我之前写的一个谓词分析的脚本iirpt.sql),以下就是sql中经常使用的谓词
NAME LAST_DATE EQUALITY EQUIJOIN NONEEQUIJOIN RANGE LIKE NULL
------------------------------ ------------------- ---------- ---------- ------------ ---------- ---------- ----------
RELYTIME 2012-05-23 12:22:56 0 0 0 140 0 0
TOPICID 2012-05-23 03:11:00 753 1781 0 0 0 0
DELSIGN 2012-05-23 03:11:00 1357 0 0 0 0 0
POSTUSERID 2012-05-23 03:11:00 1438 871 0 0 0 0
ID 2012-05-23 02:53:51 1645 1 0 0 0 0
2.2根据谓词的分析可以尝试建立一个复合索引,来减少sql中的排序操作
create index IDX_DBBS_RELY_TOPICID on DBBS_RELY (TOPICID, RELYTIME, ID);
在此的索引虽然冗余了一个字段ID(本来主是主键),但是相比执行次数较多的查询来说,如何取舍自然很明白。
2.3再次查看增加完复合索引的执行计划
Plan hash value: 2435787701
---------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 40 | 134K| 33 (0)| 00:00:01 |
|* 1 | VIEW | | 40 | 134K| 33 (0)| 00:00:01 |
|* 2 | COUNT STOPKEY | | | | | |
| 3 | VIEW | | 40 | 134K| 33 (0)| 00:00:01 |
| 4 | TABLE ACCESS BY INDEX ROWID| DBBS_RELY | 40 | 6520 | 33 (0)| 00:00:01 |
|* 5 | INDEX RANGE SCAN | IDX_DBBS_RELY_TOPICID | 2626 | | 3 (0)| 00:00:01 |
---------------------------------------------------------------------------------------------------------
此处减少了SORT ORDER BY STOPKEY操作,成本从原来的1160降低到33
SORT ORDER BY STOPKEY的优化
原文:http://blog.itpub.net/26390465/viewspace-1794551/