<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    [收藏]SQL優(yōu)化

    Posted on 2006-03-20 20:53 ikingqu 閱讀(763) 評(píng)論(1)  編輯  收藏 所屬分類: DataBase
    最近做項(xiàng)目發(fā)現(xiàn)很多SQL沒(méi)有優(yōu)化: 現(xiàn)在總結(jié)幾種優(yōu)化方式.
    ?首先先了解一個(gè)SQL語(yǔ)句的執(zhí)行過(guò)程分3步: 語(yǔ)法分析(parase)與編譯,執(zhí)行,取數(shù)據(jù).
    1: 在語(yǔ)法分析與編譯時(shí):oracle 使用哈希函數(shù)為SQL語(yǔ)句在庫(kù)緩存中分配一個(gè)SQL區(qū),
    首先檢查語(yǔ)句是否存在,若在,則查詢數(shù)據(jù)庫(kù)字典、檢查必須的權(quán)限。
    若無(wú),需要語(yǔ)法分析與編譯。所以SQL語(yǔ)句存在與內(nèi)存中,將減少分析,編譯時(shí)間。
    SQL語(yǔ)句的分析與編譯占整個(gè)語(yǔ)句運(yùn)行過(guò)程的60%的時(shí)間,SQL優(yōu)化的目標(biāo)就是減少分析與編譯的時(shí)間,共享代碼。

    查詢SQL語(yǔ)句分析與編譯的時(shí)間:
    select * from v$sysstat
    where name in ('parse time cpu','parse time elapsed','parse count (hard)')

    一個(gè)SQL語(yǔ)句的響應(yīng)時(shí)間(elapsed time )應(yīng)該是服務(wù)時(shí)間+等待時(shí)間.
    服務(wù)時(shí)間= CPU執(zhí)行時(shí)間.
    等待時(shí)間 可以從v$system_event
    select total_waits, total_timeouts, time_waited, average_wait ,event
    from v$system_event
    where event='latch free'
    所以解析一個(gè)SQL語(yǔ)句的平均等待時(shí)間是"等待時(shí)間/parse count" 這個(gè)值接近0
    通過(guò)數(shù)據(jù)字典v$sqlare,可以查詢到頻繁被分析與編譯的SQL語(yǔ)句.應(yīng)該減少SQL語(yǔ)句的分析與編譯的次數(shù).

    2: 將常用的實(shí)體駐留內(nèi)存.
    為了減少分析與編譯時(shí)間,可以將常用的的實(shí)體如: 存儲(chǔ)過(guò)程,包等,盡可能駐留在內(nèi)存區(qū)域.
    ?1)預(yù)留內(nèi)存空間. sql> show parameter shared_pool_reserved_size
    ?????? 2)將頻繁使用的實(shí)體駐留在內(nèi)存中. 在使用DBMS_SHARED_POOL程序包前,必須首先運(yùn)行系統(tǒng)提供的程序包: dbmspool.sql 和prvtpool.plb
    ?在加載這兩個(gè)程序包后,自動(dòng)生成所需的包.
    ????? 加載: sql> @/u01/app/oracle/product/8.17/rdbms/admin/dbmspool.sql
    ?????????? sql> @/u01/app/oracle/product/8.17/rdbms/admin/prvtpool.sql
    ????? 包DBMS_SHARED_POOL包含以下存儲(chǔ)過(guò)程.
    ????? dbms_shared_pool.keep 用于將實(shí)體保存內(nèi)存. dbms_shared_pool.keep(object in varchar2,[type in char default p]);
    ???????????????????????????? object 表示參數(shù)名, type 表示被駐留內(nèi)存的實(shí)體類型;P 表示存儲(chǔ)過(guò)程,C表示光標(biāo),R表示觸發(fā)器,默認(rèn)P
    ???????
    ????? dbms_shared_pool.unkeep 用于取消被設(shè)置進(jìn)入內(nèi)存的實(shí)體. dbms_shared_pool.unkeep(object in varchar2,[type in char default p]);
    ???????????????????????????? object 表示參數(shù)名, type 表示被駐留內(nèi)存的實(shí)體類型;P 表示存儲(chǔ)過(guò)程,C表示光標(biāo),R表示觸發(fā)器,默認(rèn)P
    ?????
    ????? dbms_shared_pool.size(minsize in number)

    ????? select name ,type ,source_size+code_size+parsed_size+error_size "total bytes"
    ????? from dba_object_size
    ????? where owner='SCOTT'

    3: 創(chuàng)建索引.
    ?? select index_name,table_owner, table_name, tablespace_name from all_indexes
    ??
    ?? select user_indexes.TABLE_NAME, user_indexes.INDEX_NAME,uniqueness, column_name
    ?? from user_ind_columns ,user_indexes
    ?? where user_ind_columns.INDEX_NAME=user_indexes.INDEX_NAME
    ?? and user_ind_columns.TABLE_NAME=user_indexes.TABLE_NAME
    ?? order by user_indexes.TABLE_TYPE,user_indexes.TABLE_NAME,user_indexes.INDEX_NAME,user_ind_columns.COLUMN_POSITION

    4: 創(chuàng)建聚簇(cluster): 是一組存儲(chǔ)在一起的有共同列或經(jīng)常一起使用的表,被聚簇的兩個(gè)表只有一個(gè)數(shù)據(jù)段.聚簇表在存儲(chǔ)時(shí),在物理層將子表合并到父表中,這樣就少了表的連接時(shí)間.

    5: 創(chuàng)建哈希索引.
    ?
    6: SQL優(yōu)化器: 基于成本的優(yōu)化器CBO(cose_based)和基于規(guī)則RBO(rule_based)
    ?? sql> show parameter OPTIMIZER_MODE
    ?? 可以修改參數(shù)文件: initSID.ora,增加: optimizer_Mode={CHOOSE| RULE| FIRST_ROWS|ALL_ROWS}
    ? all_rows , first_rows(n)基于成本; rule 基于規(guī)則,choose基于規(guī)則、成本。
    ? /*+ ordered*/
    ? /*+ rule */
    ? /*+ first_rows(50) */

    ? /*+ordered star*/
    ? 寫(xiě)發(fā):?
    ? alter system flush shared_pool;
    select /*+ rule */ aa from visit

    原文鏈接:http://m.tkk7.com/yanmin/archive/2006/03/20/36332.html

    Feedback

    # re: [轉(zhuǎn)]SQL優(yōu)化  回復(fù)  更多評(píng)論   

    2006-03-20 23:41 by 風(fēng)向逆轉(zhuǎn) - Java無(wú)限
    SQL優(yōu)化 補(bǔ)充
    作者blog:http://blog.csdn.net/baggio785/

    Sql優(yōu)化是一項(xiàng)復(fù)雜的工作,以下的一些基本原則是本人看書(shū)時(shí)所記錄下來(lái)的,很明確且沒(méi)什么廢話:
    1. 索引的使用:
    (1).當(dāng)插入的數(shù)據(jù)為數(shù)據(jù)表中的記錄數(shù)量的10%以上,首先需要?jiǎng)h除該表的索引來(lái)提高數(shù)據(jù)的插入效率,當(dāng)數(shù)據(jù)插入后,再建立索引。
    (2).避免在索引列上使用函數(shù)或計(jì)算,在where子句中,如果索引是函數(shù)的一部分,優(yōu)化器將不再使用索引而使用全表掃描。如:
    低效:select * from dept where sal*12 >2500;
    高效:select * from dept where sal>2500/12;
    (3).避免在索引列上使用not和 “!=”,索引只能告訴什么存在于表中,而不能告訴什么不存在于表中,當(dāng)數(shù)據(jù)庫(kù)遇到not 和 “!=”時(shí),就會(huì)停止使用索引而去執(zhí)行全表掃描。
    (4).索引列上>=代替>
    低效:select * from emp where deptno > 3
    高效:select * from emp where deptno >=4
    兩者的區(qū)別在于,前者dbms將直接跳到第一個(gè)deptno等于4的記錄,而后者將首先定位到deptno等于3的記錄并且向前掃描到第一個(gè)deptno大于3的。
    (5).非要對(duì)一個(gè)使用函數(shù)的列啟用索引,基于函數(shù)的索引是一個(gè)較好的方案。
    2. 游標(biāo)的使用:
    當(dāng)在海量的數(shù)據(jù)表中進(jìn)行數(shù)據(jù)的刪除、更新、插入操作時(shí),用游標(biāo)處理的效率是最慢的,但是游標(biāo)又是必不可少的,所以正確使用游標(biāo)十分重要:
    (1). 在數(shù)據(jù)抽取的源表中使用時(shí)間戳,這樣每天的維表數(shù)據(jù)維護(hù)只針對(duì)更新日期為最新時(shí)間的數(shù)據(jù)來(lái)進(jìn)行,大大減少需要維護(hù)的數(shù)據(jù)記錄數(shù)。
    (2). 在insert和update維表時(shí)都加上一個(gè)條件來(lái)過(guò)濾維表中已經(jīng)存在的記錄,例如:
    insert into dim_customer select * from ods_customer where ods_customer.code not exists (dim_customer.code)
    ods_customer為數(shù)據(jù)源表。dim_customer為維表。
    (3). 使用顯式的游標(biāo),因?yàn)殡[式的游標(biāo)將會(huì)執(zhí)行兩次操作,第一次檢索記錄,第二次檢查too many rows這個(gè)exception,而顯式游標(biāo)不執(zhí)行第二次操作。
    3. 據(jù)抽取和上載時(shí)的sql優(yōu)化:
    (1). Where 子句中的連接順序:
    oracle采用自下而上的順序解析where子句,根據(jù)這個(gè)原理,表之間的連接必須寫(xiě)在其他where條件之前,那些可以過(guò)濾掉大量記錄的條件必須寫(xiě)在where子句的末尾。如:
    低效:select * from emp e where sal>5000 and job = ‘manager’ and 25<(select count (*) from emp where mgr=e.empno);
    高效:select * from emp e where 25<(select count(*) from emp where mgr=e.empno) and sal>5000 and job=’manager’;
    (2). 刪除全表時(shí),用truncate 替代 delete,同時(shí)注意truncate只能在刪除全表時(shí)適用,因?yàn)閠runcate是ddl而不是dml。
    (3). 盡量多使用commit
    只要有可能就在程序中對(duì)每個(gè)delete,insert,update操作盡量多使用commit,這樣系統(tǒng)性能會(huì)因?yàn)閏ommit所釋放的資源而大大提高。
    (4). 用exists替代in ,可以提高查詢的效率。
    (5). 用not exists 替代 not in
    (6). 優(yōu)化group by
    提高group by語(yǔ)句的效率,可以將不需要的記錄在group by之前過(guò)濾掉。如:
    低效:select job, avg(sal) from emp group by job having job = ‘president’ or job=’manager’;
    高效: select job, avg(sal) from emp having job=’president’ or job=’manager’ group by job;
    (7). 有條件的使用union-all 替代 union:這樣做排序就不必要了,效率會(huì)提高3到5倍。
    (8). 分離表和索引
    總是將你的表和索引建立在不同的表空間內(nèi),決不要將不屬于oracle內(nèi)部系統(tǒng)的對(duì)象存放到system表空間內(nèi)。同時(shí)確保數(shù)據(jù)表空間和索引表空間置于不同的硬盤(pán)控制卡控制的硬盤(pán)上。



    Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=623666

    posts - 4, comments - 5, trackbacks - 0, articles - 60

    Copyright © ikingqu

    主站蜘蛛池模板: 亚洲jizzjizz在线播放久| 亚洲不卡中文字幕无码| 亚洲最大免费视频网| 久久成人免费电影| 99ri精品国产亚洲| 182tv免费视视频线路一二三| 久久国产精品亚洲一区二区| 国产在线观看免费视频软件| 亚洲AV电影院在线观看| 99在线观看精品免费99| 亚洲精品中文字幕无码AV| 免费看男女下面日出水来| 亚洲人成综合在线播放| 好爽又高潮了毛片免费下载| 亚洲国产美女精品久久久| 国产亚洲福利一区二区免费看| 国产产在线精品亚洲AAVV| 在线A亚洲老鸭窝天堂| 免费成人在线电影| 亚洲国产成人久久综合一区| 国产成人精品久久免费动漫| 中中文字幕亚洲无线码| 国产精品免费一级在线观看| japanese色国产在线看免费| 亚洲国产精品福利片在线观看 | 亚洲AV福利天堂一区二区三| 亚洲成人免费网址| 亚洲精品无码永久在线观看男男| 亚洲国产精品成人久久蜜臀| 大地资源中文在线观看免费版| 亚洲视频免费一区| 国内自产拍自a免费毛片| 一本久久免费视频| 内射少妇36P亚洲区| 免费的一级片网站| 中文字幕在线免费播放| 亚洲一区免费视频| 亚洲日韩在线观看| 69av免费视频| 免费看美女午夜大片| 亚洲视频在线观看不卡|