打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Oracle调优
 从8i到10g,Oracle不断进化自己的SQL Tuning智能,一些秘籍级的优化口诀已经失效。
   但我喜欢失效,不用记口诀,操个Toad for Oracle Xpert ,按照大方向舒舒服服的调优才是爱做的事情。

1.Excution Plan
     Excution Plan是最基本的调优概念,不管你的调优吹得如何天花乱堕,结果还是要由Excution plan来显示Oracle 最终用什么索引、按什么顺序连接各表,Full Table Scan还是Access by Rowid Index,瓶颈在什么地方。如果没有它的指导,一切调优都是蒙的。


2.Toad for Oracle Xpert
    用它来调优在真的好舒服。Quest 吞并了Lecco后,将它整合到了Toad 的SQL Tunning里面:最清晰的执行计划显示,自动生成N条等价SQL、给出优化建议,不同SQL执行计划的对比,还有实际执行的逻辑读、物理读数据等等一目了然。


3.索引
   大部分的性能问题其实都是索引应用的问题,Where子句、Order By、Group By 都要用到索引。
   一般开发人员认为将索引建全了就可以下班回家了,实则还有颇多的思量和陷阱。

3.1 索引列上不要进行计算
      这是最最普遍的失效陷阱,比如where trunc(order_date)=trunc(sysdate), i+2>4。索引失效的原因也简单,索引是针对原值建的二叉树,你将列值*3/4+2折腾一番后,原来的二叉树当然就用不上了。解决的方法:
  1. 换成等价语法,比如trunc(order_date) 换成
where order_date>trunc(sysdate)-1 and order_date<trunc(sysdate)+1

  2.    特别为计算建立函数索引

create index I_XXXX on shop_order(trunc(order_date))

    3.    将计算从等号左边移到右边
 这是针对某些无心之失的纠正,把a*2>4 改为a>4/2;把TO_CHAR(zip) = '94002' 改为zip = TO_NUMBER('94002');

3.2 CBO与索引选择性
     建了索引也不一定会被Oracle用的,就像个挑食的孩子。基于成本的优化器(CBO, Cost-Based Optimizer),会先看看表的大小,还有索引的重复度,再决定用还是不用。表中有100 条记录而其中有80 个不重复的索引键值. 这个索引的选择性就是80/100 = 0.8,留意Toad里显示索引的Selective和Cardinailty。实在不听话时,就要用hints来调教。
     另外,where语句存在多条索引可用时,只会选择其中一条。所以索引也不是越多越好:)

3.3 索引重建
     传说中数据更新频繁导致有20%的碎片时,Oracle就会放弃这个索引。宁可信其有之下,应该时常alter index <INDEXNAME> rebuild一下。

3.4 其他要注意的地方
      不要使用Not,如goods_no != 2,要改为

where goods_no>2 or goods_no<2

      不要使用is null , 如WHERE DEPT_CODE IS NOT NULL 要改为

WHERE DEPT_CODE >=0;

3.5 select 的列如果全是索引列时
   又如果没有where 条件,或者where条件全部是索引列时,Oracle 将直接从索引里获取数据而不去读真实的数据表,这样子理论上会快很多,比如

select order_no,order_time from shop_order where shop_no=4

当order_no,order_time,shop_no 这三列全为索引列时,你将看到一个和平时完全不同的执行计划。

3.6 位图索引
     传说中当数据值较少,比如某些表示分类、状态的列,应该建位图索引而不是普通的二叉树索引,否则效率低下。不过看执行计划,这些位图索引鲜有被Oracle临幸的。
 

4.减少查询往返和查询的表
这也是很简单的大道理,程序与Oracle交互的成本极高,所以一个查询能完成的不要分开两次查,如果一个循环执行1万条查询的,怎么都快不到哪里去了。

4.1 封装PL/SQL存储过程
  最高级的做法是把循环的操作封装到PL/SQL写的存储过程里,因为存储过程都在服务端执行,所以没有数据往返的消耗。

4.2 封装PL/SQL内部函数
  有机会,将一些查询封装到函数里,而在普通SQL里使用这些函数,同样是很有效的优化。

4.3 Decode/Case
  但存储过程也麻烦,所以有case/decode把几条条件基本相同的重复查询合并为一条的用法:

SELECT
 
COUNT(CASE WHEN price < 13 THEN 1 ELSE null END) low,
 
COUNT(CASE WHEN price BETWEEN 13 AND 15 THEN 1 ELSE null END) med,
 
COUNT(CASE WHEN price > 15 THEN 1 ELSE null END) high
FROM products;

4.4 一种Where/Update语法

SELECT TAB_NAME FROM TABLES
WHERE (TAB_NAME,DB_VER) = (( SELECT TAB_NAME,DB_VER)
FROM TAB_COLUMNS WHERE VERSION = 604)

UPDATE EMP
SET (EMP_CAT, SAL_RANGE)
= (SELECT MAX(CATEGORY)FROM EMP_CATEGORIES)


5.其他优化

5.1RowID和ROWNUM
     连Hibernate 新版也支持ROWID了,证明它非常有用。比如号称删除重复数据的最快写法:

DELETE FROM EMP E
WHERE E.ROWID > (SELECT MIN(X.ROWID)
FROM EMP X
WHERE X.EMP_NO = E.EMP_NO);

 

6.终极秘技 - Hints
   这是Oracle DBA的玩具,也是终极武器,比如Oracle在CBO,RBO中所做的选择总不合自己心水时,可以用它来强力调教一下Oracle,结果经常让人喜出望外。
   如果开发人员没那么多时间来专门学习它,可以依靠Toad SQL opmitzer 来自动生成这些提示,然后对比一下各种提示的实际效果。不过随着10g智能的进化,hints的惊喜少了。

7. 找出要优化的Top SQL
    磨了这么久的枪,如果找不到敌人是件郁闷的事情。
    幸亏10g这方面做得非常好。进入Web管理界面,就能看到当前或者任意一天的SQL列表,按性能排序。
    有了它,SQL Trace和TKPROF都可以不用了。

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
通过建立索引提高数据库查询速度的原理
TOAD中文文档 - 入门技术
使用hint优化 Oracle SQL语句方法30例
Oracle优化----索引原理篇
转载-----通过分析SQL语句的执行计划优化SQL(总结)
Oracle执行计划详解
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服