16 SQL Tuning Overview
16.1 Introduction to SQL Tuning
Identifying high load or top SQL statements that are responsible for a large share of the application workload and system resources, by reviewing past SQL execution history available in the system
Verifying that the execution plans produced by the query optimizer for these statements perform reasonably
Implementing corrective actions to generate better execution plans for poorly performing SQL statements
OLTP 不推荐使用并行查询 16.3 Identifying High-Load SQL
toad 有工具定义, 排序, 可以看到比较耗费资源的SQL情况
V$SQL view:
V$SQLSTATS : The data in V$SQLSTATS should be ordered by resource usage
V$SQLSTATS.BUFFER_GETS : Buffer gets ( for high CPU using statements)
V$SQLSTATS.DISK_READS: Disk reads (for high I/O statements)
V$SQLSTATS.SORTS : sorts (for many sorts)
SQL Trace : TKPROF 读取 这个 SQL Trace 文件. After you have identified the candidate SQL statements, the next stage is to gather information that is necessary to examine the statements and tune them.
Information to Gather During Tuning
(1) Complete SQL text from V$SQLTEXT
(2) Structure of the tables referenced in the SQL statement, usually by describing the table in SQL*Plus
(3) Definitions of any indexes (columns, column orders), and whether the indexes are unique or non-unique
(4) Optimizer statistics for the segments (including the number of rows each table, selectivity of the index columns), including the date when the segments were last analyzed
(5) Definitions of any views referred to in the SQL statement
(6) Repeat steps two, three, and four for any tables referenced in the view definitions found in step five
(7) Optimizer plan for the SQL statement (either from EXPLAIN PLAN, V$SQL_PLAN, or the TKPROF output)
(8) Any previous optimizer plans for that SQL statement 16.5 Developing Efficient SQL Statements
The query optimizer uses statistics gathered on tables and indexes when determining the optimal execution plan.
If these statistics have not been gathered, or if the statistics are no longer representative of the data stored within the database,
then the optimizer does not have sufficient information to generate the best plan. When tuning (or writing) a SQL statement in an OLTP environment, the goal is to drive from the table that has the most selective filter.
> The driving table has the best filter
> The join order in each step returns the fewest number of rows to the next step (that is, the join order should reflect, where possible, going to the best not-yet-used filters).
> The join method is appropriate for the number of rows being returned. For example, nested loop joins through indexes may not be optimal when the statement returns many rows.
> The database uses views efficiently. Look at the SELECT list to see whether access to the view is necessary.
> There are any unintentional Cartesian products (even with small tables)
> Each table is being accessed efficiently: 16.5.3 Restructuring the SQL Statements 16.5.3.1 Compose Predicates Using AND and =, To improve SQL efficiency, use equijoins whenever possible
16.5.3.2 Avoid Transformed Columns in the WHERE Clause, 例如:
good: WHERE a.order_no = b.order_no
bad: WHERE TO_NUMBER (SUBSTR(a.order_no, INSTR(b.order_no, '.') - 1)) = TO_NUMBER (SUBSTR(a.order_no, INSTR(b.order_no, '.') - 1))
Avoid mixed-mode expressions, and beware of implicit type conversions. When you want to use an index on the VARCHAR2 column charcol, but the WHERE clause looks like this:
AND charcol = numexpr, where numexpr is an expression of number type, Oracle Database translates that expression into: AND TO_NUMBER(charcol) = numexpr
Avoid the following kinds of complex expressions:
col1 = NVL (:b1,col1)
NVL (col1,-999) = ....
TO_DATE(), TO_NUMBER(), and so on
EX:
SELECT employee_num, full_name Name, employee_id
FROM mtl_employees_current_view
WHERE (employee_num = NVL (:b1,employee_num)) AND (organization_id=:1)
ORDER BY employee_num; SELECT employee_num, full_name Name, employee_id
FROM mtl_employees_current_view
WHERE (employee_num = :b1) AND (organization_id=:1)
ORDER BY employee_num; If a column of type NUMBER is used in a WHERE clause to filter predicates with a literal value,
then use a TO_NUMBER function in the WHERE clause predicate to ensure you can use the index on the NUMBER column.
For example, if numcol is a column of type NUMBER, then a WHERE clause containing numcol=TO_NUMBER('') enables the database to use the index on numcol. If a query joins two tables, and if the join columns have different data types (for example, NUMBER and VARCHAR2),
then Oracle Database implicitly performs data type conversion. For example, if the join condition is varcol=numcol,
then the database implicitly converts the condition to TO_NUMBER(varcol)=numcol. If an index exists on the varcol column,
then explicitly set the type conversion to varcol=TO_CHAR(numcol), thus enabling the database to use the index.
16.5.3.3 Write Separate SQL Statements for Specific Tasks
It is always better to write separate SQL statements for different tasks, but if you must use one SQL statement,
then you can make a very complex statement slightly less complex by using the UNION ALL operator.
SELECT info
FROM tables
WHERE ...
AND somecolumn BETWEEN DECODE(:loval, 'ALL', somecolumn, :loval)
AND DECODE(:hival, 'ALL', somecolumn, :hival);
The database cannot use an index on the somecolumn column, because the expression involving that column uses the same column on both sides of the BETWEEN.
重写上边的语句, 可以走索引
SELECT /* change this half of UNION ALL if other half changes */ info
FROM tables
WHERE ...
AND somecolumn BETWEEN :loval AND :hival
AND (:hival != 'ALL' AND :loval != 'ALL')
UNION ALL
SELECT /* Change this half of UNION ALL if other half changes. */ info
FROM tables
WHERE ...
AND (:hival = 'ALL' OR :loval = 'ALL');
综上, 基本上是说, 你要对你查询中重要的列的类型做好控制, 尽量不要让隐式转换发生.
16.5.4 Controlling the Access Path and Join Order with Hints
你可以通过hint来指导oracle, 比如:
SELECT /*+ FULL(e) */ e.last_name
FROM employees e
WHERE e.job_id = 'CLERK';
Join order can have a significant effect on performance. The main objective of SQL tuning is to avoid performing unnecessary work to access rows that do not affect the result
Avoid a full-table scan if it is more efficient to get the required rows through an index.
Avoid using an index that fetches 10,000 rows from the driving table if you could instead use another index that fetches 100 rows.
Choose the join order so as to join fewer rows to tables later in the join order.
EX:
SELECT info
FROM taba a, tabb b, tabc c
WHERE a.acol BETWEEN 100 AND 200
AND b.bcol BETWEEN 10000 AND 20000
AND c.ccol BETWEEN 10000 AND 20000
AND a.key1 = b.key1
AND a.key2 = c.key2;
(1) Choose the driving table and the driving index (if any).
(2) Choose the best join order, driving to the best unused filters earliest.
(3) You can use the ORDERED or STAR hint to force the join order.
16.5.4.1 Use Caution When Managing Views
连接比较复杂的view时, 要特别小心
EX :
CREATE OR REPLACE VIEW emp_dept
AS
SELECT d.department_id, d.department_name, d.location_id,
e.employee_id, e.last_name, e.first_name, e.salary, e.job_id
FROM departments d
,employees e
WHERE e.department_id (+) = d.department_id; SELECT v.last_name, v.first_name, l.state_province
FROM locations l, emp_dept v
WHERE l.state_province = 'California'
AND v.location_id = l.location_id (+);
--------------------------------------------------------------------------------
| Operation | Name | Rows | Bytes| Cost | Pstart| Pstop |
--------------------------------------------------------------------------------
| SELECT STATEMENT | | | | | | |
| FILTER | | | | | | |
| NESTED LOOPS OUTER | | | | | | |
| VIEW |EMP_DEPT | | | | | |
| NESTED LOOPS OUTER | | | | | | |
| TABLE ACCESS FULL |DEPARTMEN | | | | | |
| TABLE ACCESS BY INDEX|EMPLOYEES | | | | | |
| INDEX RANGE SCAN |EMP_DEPAR | | | | | |
| TABLE ACCESS BY INDEX R|LOCATIONS | | | | | |
| INDEX UNIQUE SCAN |LOC_ID_PK | | | | | |
--------------------------------------------------------------------------------
16.5.4.2 Store Intermediate Results
materialized views 也是其中的一种
16.5.9.1 Combine Multiples Scans Using CASE Expressions
EX:
SELECT COUNT (*)
FROM employees
WHERE salary < 2000; SELECT COUNT (*)
FROM employees
WHERE salary BETWEEN 2000 AND 4000; SELECT COUNT (*)
FROM employees
WHERE salary>4000;
以上3个, 替换成一个更有效率的SQL, 利用 case
SELECT COUNT (CASE WHEN salary < 2000
THEN 1 ELSE null END) count1,
COUNT (CASE WHEN salary BETWEEN 2001 AND 4000
THEN 1 ELSE null END) count2,
COUNT (CASE WHEN salary > 4000
THEN 1 ELSE null END) count3
FROM employees;
16.5.9.3 Modify All the Data Needed in One Statement
一个事务, 结合在一起
EX:
BEGIN
FOR pos_rec IN (SELECT *
FROM order_positions
WHERE order_id = :id) LOOP
DELETE FROM order_positions -- 事务1
WHERE order_id = pos_rec.order_id AND
order_position = pos_rec.order_position;
END LOOP;
DELETE FROM orders -- 事务2
WHERE order_id = :id;
END;
以上, 事务1 和 事务2 其实是一个操作, 类似银行转账, 所以, 最好放在一个begin end 里.
16 SQL Tuning Overview的更多相关文章
- 【转】使用SQL Tuning Advisor STA优化SQL
SQL优化器(SQL Tuning Advisor STA)是Oracle10g中推出的帮助DBA优化工具,它的特点是简单.智能,DBA值需要调用函数就可以给出一个性能很差的语句的优化结果.下面介绍一 ...
- 如何用 SQL Tuning Advisor (STA) 优化SQL语句
在Oracle10g之前,优化SQL是个比较费力的技术活,不停的分析执行计划,加hint,分析统计信息等等.在10g中,Oracle推出了自己的SQL优化辅助工具: SQL优化器(SQL Tuning ...
- 使用ORACLE SQL Tuning advisor快速优化低效的SQL语句
ORACLE10G以后版本的SQL Tuning advisor可以从以下四个方面给出优化方案 (1)为统计信息丢失或失效的对象收集统计信息 (2)考虑优化器的任何数据偏差.复杂谓词或失效的统计信 ...
- 老李分享: Oracle Performance Tuning Overview 翻译下
1.2性能调优特性和工具 Effective data collection and analysis isessential for identifying and correcting perfo ...
- 老李分享: Oracle Performance Tuning Overview 翻译
老李分享: Oracle Performance Tuning Overview 翻译 poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工 ...
- Oracle调整顾问(SQL Tuning Advisor 与 SQL Access Advisor
在Oracle数据库出现性能问题时,使用Oracle本身的工具包,给出合理的调优建议是比较省力的做法. tuning advisor 是对输入的sql set的执行计划进行优化accsee advis ...
- rac数据库默认sql tuning advisor,导致大量library cache lock
rac数据库默认sql tuning advisor,导致大量library cache lock 问题现象:客户反映周六周日固定十点钟,一个程序会特别慢(大概10分钟),平时1到2秒.查看当时的日志 ...
- Oracle SQL Tuning Advisor 测试
如果面对一个需要优化的SQL语句,没有很好的想法,可以先试试Oracle的SQL Tuning Advisor. SQL> select * from v$version; BANNER --- ...
- 怎样使用oracle 的DBMS_SQLTUNE package 来执行 Sql Tuning Advisor 进行sql 自己主动调优
怎样使用oracle 的DBMS_SQLTUNE package 来执行 Sql Tuning Advisor 进行sql 自己主动调优 1>.这里简单举个样例来说明DBMS_SQLTUN ...
随机推荐
- m=m++,结果让你大吃一惊。
如图,本来以为m=m++和m++是同一个效果,没想到m的值居然还是0. 原来m++是一个表达式,是有返回值的,它的返回值就是m自加前的值,Java对自加是这样处理的:首先把m的值(注意是值,不是引用) ...
- 解决python "Non-ASCII character"错误
原文http://jingyan.baidu.com/article/219f4bf7d04887de442d3899.html 1.出现问题的原因:程序中的编码错误,python默认是acii模式, ...
- perl基础
perl比较好的博客:http://www.cnblogs.com/cosiray/archive/2012/03/18/2404371.html 以分析一个简单的pm文件为例 # # オプションの取 ...
- CocoaPod遇到更新不了的原因
CocoaPods 1.0.1 is available. To update use: `gem install cocoapods` Until we reach version 1.0 the ...
- tomcat server需要重启的时刻
1.修改了web project的任何配置文件,都需要重启tomcat 2.修改了任何java class文件,都需要重启tomcat server 3.在项目中添加了任何的文件,包括配置文件.jav ...
- VS2010--2013使用技巧及使用过程中遇到的问题
Microsoft Visual Studio 2010 --2013默认情况下是不显示代码的行号的,但是在编译出错时,可点击下面输出窗口中的错误提示进行定位.但是这样操作起来你有没有感觉到不方便呢. ...
- 日常开发使用SVN命令
现在把我日常开发中用到的svn命令总结出来,做个备忘,其实真正用到也就那几个. 如果遇到参数不知道使用或其它困难请使用:svn --help 得到帮助 1)检出: svn co svn地址 本地路径 ...
- [tp3.2.1]查询(2)
<?php namespace Home\Controller; use Think\Controller; use Think\Model; class QueryController ext ...
- Json.net对于导航属性的处理(解决对象循环引用)
对于两张表A.B多对多的关系中,A的导航属性中有B,B的导航属性中有A,这样Json.net对A或者B对象序列化时会形成死循环 所以对于导航属性要加标签 首先在A.B实体类工程(Model)中引用Js ...
- Arcgis Server 默认服务端口号修改方法
本人安装Arcgis Server 10.2之后发布了一个地图服务,该服务默认使用的端口号是6080,本人使用的是教育网,使用教育网均能正常使用该服务,但是使用电信或者移动网络均不能正常访问该网站. ...