17、Sql优化

SQL 优化的实质

就是在:

结果正确的前提下,用优化器可以识别的语句,充份利用索引,执行过程中访问尽量少的数据块,减少表扫描的 I/O 次数,尽量避免全表扫描和其他额外开销。



oracle 数据库常用的两种优化器:

RBO(rule-based-optimizer)和 CBO(cost-based-optimizer)。目前更多地采用 CBO(cost-based-optimizer)基于开销的优化器。

在 CBO 方式下,Oracle 会根据表及索引的状态信息来选择计划;

在 RBO 方式下,Oracle 会根据自己内部设置的一些规则来决定选择计划,

例如 oracle 会根据以下优先级来选择执行计划(越靠前,rank 越低,越快):



尽量少用 IN 操作符

基本上所有的 IN 操作符都可以用 EXISTS 代替,在选择 IN 或 EXIST 操作时,要根据主子表数据量大小来具体考虑

尽量用 NOT EXISTS 或者外连接替代 NOT IN 操作符

因为 NOT IN 不能应用表的索引



尽量不用“<>”或者“!=”操作符

不等于操作符是永远不会用到索引的,因此对它的处理只会产生全表扫描。比如:a<>0 改为a>0 or a<0



在设计表时,把索引列设置为NOTNULL

判断字段是否为空一般是不会应用索引的,因为 B 树索引是不索引空值的。



尽量不用通配符“%”或者“_”作为查询字符串的第一个字符

当通配符“%”或者“_”作为查询字符串的第一个字符时,索引不会被使用。比如用 T 表中 Column1 LIKE „%5400%‟ 这个条件会产生全表扫描,如果改成 Column1 ‟X5400%‟ OR Column1 LIKE ‟B5400%‟ 则会利用 Column1 的索引进行两个范围的查询,性能肯定大大提高



Where子句中避免在索引列上使用计算

如果索引不是基于函数的,那么当在 Where 子句中对索引列使用函数时,索引不再起作用。因此 Where 子句中避免在索引列上使用计算。比如:       substr(no,1,4)=‟5400‟,优化处理:no like „5400%‟      trunc(hiredate)=trunc(sysdate),优化处理:hiredate >=trunc(sysdate) and hiredate



用“>=”替代“>”

大于或小于操作符一般情况下是不用调整的,因为它有索引就会采用索引查找,但有的情况下可以对它进行优化,如一个表有100 万记录,一个数值型字段 A, 30 万记录的 A=0,30 万记录的 A=1,39 万记录的 A=2,1 万记录的 A=3。那么执行 A>2 与 A>=3 的效果就有很大的区别了,因为 A>2 时 ORACLE 会先找出为 2 的记录索引再进行比较,而 A>=3 时 ORACLE 则直接找到=3 的记录索引。



利用 SGA 共享池,避开 parse 阶段

同一功能同一性能不同写法 SQL 的影响  

    如一个 SQL 在 A 程序员写的为      Select * fromzl_yhjbqk  

    B程序员写的为      Select * from dlyx.zl_yhjbqk(带表所有者的前缀)  

    C程序员写的为      Select * from DLYX.ZLYHJBQK(大写表名)  

    D程序员写的为      Select * from DLYX.ZLYHJBQK(中间多了空格)  

     以上四个 SQL 在 ORACLE 分析整理之后产生的结果及执行的时间是一样的,但是从 ORACLE 共享内存 SGA 的原理,可以得出 ORACLE 对每个 SQL 都会对其进行一次分析,并且占用共享内存,如果将 SQL 的字符串及格式写得完全相同则 ORACLE 只会分析一次,共享内存也只会留下一次的分析结果,这不仅可以减少分析 SQL 的时间,而且可以减少共享内存重复的信息,ORACLE 也可以准确统计 SQL的执行频率。  

不同区域出现的相同的 Sql 语句要保证查询字符完全相同,建议经常使用变量来代替常量,以尽量使用重复 sql 代码,以利用 SGA 共享池,避开 parse 阶段,防止相同的 Sql 语句被多次分析,提高执行速度。因此使用存储过程,是一种很有效的提高share pool 共享率,跳过 parse 阶段,提高效率的办法。



WHERE后面的条件顺序要求

WHERE 后面的条件,表连接语句写在最前,可以过滤掉最大数量记录的条件居后。比如:     Select * from zl_yhjbqk where dy_dj = '1KV以下' and xh_bz=1  

Select * from zl_yhjbqk where xh_bz=1  and dy_dj = '1KV以下'  

以上两个 SQL 中 dy_dj(电压等级)及 xh_bz(销户标志)两个字段都没进行索引,所以执行的时候都是全表扫描,第一条SQL的dy_dj = '1KV以下'条件在记录集内比率为99%,而 xh_bz=1 的比率只为 0.5%,在进行第一条 SQL 的时候 99%条记录都进行 dy_dj 及 xh_bz的比较,而在进行第二条 SQL 的时候 0.5%条记录都进行 dy_dj 及 xh_bz 的比较,以此可以得出第二条 SQL 的 CPU 占用率明显比第一条低。


使用表的别名,并将之作为每列的前缀

当在 Sql 语句中连接多个表时,使用表的别名,并将之作为每列的前缀。这样可以减少解析时间。



进行了显式或隐式的运算的字段不能进行索引

比如: ss_df+20>50,优化处理:ss_df>30 „X‟||hbs_bh>‟X5400021452‟,优化处理:hbs_bh>‟5400021542‟     sk_rq+5=sysdate,优化处理:sk_rq=sysdate-5     hbs_bh=5401002554,优化处理:hbs_bh=‟ 5401002554‟,注:此条件对 hbs_bh 进行隐式的 to_number 转换,因为 hbs_bh 字段是字符型。 



用 UNION ALL 代替UNION

UNION 是最常用的集操作,使多个记录集联结成为单个集,对返回的数据行有唯一性要求,所以 oracle 就需要进行 SORT UNIQUE 操作(与使用 distinct 时操作类似),如果结果集又比较大,则操作会比较慢; UNION ALL 操作不排除重复记录行,所以会快很多,如果数据本身重复行存在可能性较小时,用 union all 会比用 union 效率高很多!



其他操作

尽量使用 packages: Packages 在第一次调用时能将整个包 load 进内存,对提高性能有帮助。 

尽量使用 cached sequences 来生成 primary key :提高主键生成速度和使用性能。 

很好地利用空间:如用 VARCHAR2 数据类型代替 CHAR 等 

使用 Sql 优化工具:sqlexpert;toad;explain-table;PL/SQL;OEM


通过改变 oracle 的 SGA 的大小

SGA:数据库的系统全局区。 SGA 主要由三部分构成:共享池、数据缓冲区、日志缓冲区



©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,026评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,655评论 1 296
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,726评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,204评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,558评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,731评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,944评论 2 314
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,698评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,438评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,633评论 2 247
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,125评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,444评论 3 255
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,137评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,103评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,888评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,772评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,669评论 2 271

推荐阅读更多精彩内容

  • 转 # https://www.cnblogs.com/easypass/archive/2010/12/ 08/...
    吕品㗊阅读 9,620评论 0 44
  • 1. 问题的提出## 在应用系统开发初期,由于开发数据库数据比较少,对于查询SQL语句,复杂视图的的编写等体会不出...
    七寸知架构阅读 5,284评论 1 111
  • 从知道你要参加《跨界歌王》我就开始期待,我对你有无数种想象,我甚至,悄悄奢望能看到那时候的吴一线。 录制那天有人在...
    段小样阅读 407评论 2 3
  • 学习真好 能够学的新知识真的很好 现在做学生让你在这专心的学习 有这样的环境与条件真的是太好了 感觉一天没读书 练...
    阿楠的小窝阅读 47评论 0 0
  • ⑴精读文章的收获:梳理文章内容,构建知识框架,使自己可以将文章串连起来。 ⑵怦然心动的单词(可以说是熟词生意):a...
    旅一47闫俊敏阅读 252评论 0 1