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

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

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

    The important thing in life is to have a great aim , and the determination

    常用鏈接

    統計

    IT技術鏈接

    保險相關

    友情鏈接

    基金知識

    生活相關

    最新評論

    SQL語句優化技術分析

    操作符優化

    IN 操作符

    IN 寫出來的 SQL 的優點是比較容易寫及清晰易懂,這比較適合現代軟件開發的風格。

    但是用 IN SQL 性能總是比較低的,從 ORACLE 執行的步驟來分析用 IN SQL 與不用 IN SQL 有以下區別:

    ?????? ORACLE 試圖將其轉換成多個表的連接,如果轉換不成功則先執行 IN 里面的子查詢,再查詢外層的表記錄,如果轉換成功則直接采用多個表的連接方式查詢。由此可見用 IN SQL 至少多了一個轉換的過程。一般的 SQL 都可以轉換成功,但對于含有分組統計等方面的 SQL 就不能轉換了。

    ?????? 推薦方案:在業務密集的 SQL 當中盡量不采用 IN 操作符。

    NOT IN操作符

    ?????? 此操作是強列推薦不使用的,因為它不能應用表的索引。

    ?????? 推薦方案:用 NOT EXISTS 或(外連接 + 判斷為空)方案代替

    <> 操作符(不等于)

    ?????? 不等于操作符是永遠不會用到索引的,因此對它的處理只會產生全表掃描。

    推薦方案:用其它相同功能的操作運算代替,如

    ?????? a<>0 改為 a>0 or a<0

    ?????? a<>’’ 改為 a>’’

    IS NULL IS NOT NULL操作(判斷字段是否為空)

    ?????? 判斷字段是否為空一般是不會應用索引的,因為 B 樹索引是不索引空值的。

    ?????? 推薦方案:

    用其它相同功能的操作運算代替,如

    ?????? a is not null 改為 a>0 a>’’ 等。

    ?????? 不允許字段為空,而用一個缺省值代替空值,如業擴申請中狀態字段不允許為空,缺省為申請。

    ?????? 建立位圖索引(有分區的表不能建,位圖索引比較難控制,如字段值太多索引會使性能下降,多人更新操作會增加數據塊鎖的現象)

    > < 操作符(大于或小于操作符)

    ?????? 大于或小于操作符一般情況下是不用調整的,因為它有索引就會采用索引查找,但有的情況下可以對它進行優化,如一個表有 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 的記錄索引。

    LIKE操作符

    LIKE 操作符可以應用通配符查詢,里面的通配符組合可能達到幾乎是任意的查詢,但是如果用得不好則會產生性能上的問題,如 LIKE ‘%5400%’ 這種查詢不會引用索引,而 LIKE ‘X5400%’ 則會引用范圍索引。一個實際例子:用 YW_YHJBQK 表中營業編號后面的戶標識號可來查詢營業編號 YY_BH LIKE ‘%5400%’ 這個條件會產生全表掃描,如果改成 YY_BH LIKE ’X5400%’ OR YY_BH LIKE ’B5400%’ 則會利用 YY_BH 的索引進行兩個范圍的查詢,性能肯定大大提高。

    UNION操作符

    UNION 在進行表鏈接后會篩選掉重復的記錄,所以在表鏈接后會對所產生的結果集進行排序運算,刪除重復的記錄再返回結果。實際大部分應用中是不會產生重復的記錄,最常見的是過程表與歷史表 UNION 。如:

    select * from gc_dfys

    union

    select * from ls_jg_dfys

    這個 SQL 在運行時先取出兩個表的結果,再用排序空間進行排序刪除重復的記錄,最后返回結果集,如果表數據量大的話可能會導致用磁盤進行排序。

    推薦方案:采用 UNION ALL 操作符替代 UNION ,因為 UNION ALL 操作只是簡單的將兩個結果合并后就返回。

    select * from gc_dfys

    union all

    select * from ls_jg_dfys

    SQL 書寫的影響

    同一功能同一性能不同寫法 SQL的影響

    如一個 SQL A 程序員寫的為

    ?????? Select * from zl_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 的執行頻率。

    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(銷戶標志)兩個字段都沒進行索引,所以執行的時候都是全表掃描,第一條SQLdy_dj = '1KV以下'條件在記錄集內比率為99%,而xh_bz=1的比率只為0.5%,在進行第一條SQL的時候99%條記錄都進行dy_dj及xh_bz的比較,而在進行第二條SQL的時候0.5%條記錄都進行dy_dj及xh_bz 的比較,以此可以得出第二條SQLCPU占用率明顯比第一條低。

    查詢表順序的影響

    FROM 后面的表中的列表順序會對 SQL 執行性能影響,在沒有索引及 ORACLE 沒有對表進行統計分析的情況下 ORACLE 會按表出現的順序進行鏈接,由此因為表的順序不對會產生十分耗服務器資源的數據交叉。(注:如果對表進行了統計分析, ORACLE 會自動先進小表的鏈接,再進行大表的鏈接)

    SQL語句索引的利用

    對操作符的優化(見上節)

    對條件字段的一些優化

    采用函數處理的字段不能利用索引,如:

    substr(hbs_bh,1,4)=’5400’ ,優化處理: hbs_bh like ‘5400%’

    trunc(sk_rq)=trunc(sysdate) , 優化處理:

    sk_rq>=trunc(sysdate) and sk_rq<trunc(sysdate+1)

    進行了顯式或隱式的運算的字段不能進行索引,如:

    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 字段是字符型。

    條件內包括了多個本表的字段運算時不能進行索引,如:

    ys_df>cx_df ,無法進行優化

    qc_bh||kh_bh=’5400250000’ ,優化處理: qc_bh=’5400’ and kh_bh=’250000’

    應用 ORACLE HINT(提示)處理

    提示處理是在 ORACLE 產生的 SQL 分析執行路徑不滿意的情況下要用到的。它可以對 SQL 進行以下方面的提示

    目標方面的提示:

    COST (按成本優化)

    RULE (按規則優化)

    CHOOSE (缺省)( ORACLE 自動選擇成本或規則進行優化)

    ALL_ROWS (所有的行盡快返回)

    FIRST_ROWS (第一行數據盡快返回)

    執行方法的提示:

    USE_NL (使用 NESTED LOOPS 方式聯合)

    USE_MERGE (使用 MERGE JOIN 方式聯合)

    USE_HASH (使用 HASH JOIN 方式聯合)

    索引提示:

    INDEX TABLE INDEX )(使用提示的表索引進行查詢)

    其它高級提示(如并行處理等等)

    ORACLE 的提示功能是比較強的功能,也是比較復雜的應用,并且提示只是給 ORACLE 執行的一個建議,有時如果出于成本方面的考慮 ORACLE 也可能不會按提示進行。根據實踐應用,一般不建議開發人員應用 ORACLE 提示,因為各個數據庫及服務器性能情況不一樣,很可能一個地方性能提升了,但另一個地方卻下降了, ORACLE SQL 執行分析方面已經比較成熟,如果分析執行的路徑不對首先應在數據庫結構(主要是索引)、服務器當前性能(共享內存、磁盤文件碎片)、數據庫對象(表、索引)統計信息是否正確這幾方面分析。

    操作符優化

    IN 操作符

    IN 寫出來的 SQL 的優點是比較容易寫及清晰易懂,這比較適合現代軟件開發的風格。

    但是用 IN SQL 性能總是比較低的,從 ORACLE 執行的步驟來分析用 IN SQL 與不用 IN SQL 有以下區別:

    ?????? ORACLE 試圖將其轉換成多個表的連接,如果轉換不成功則先執行 IN 里面的子查詢,再查詢外層的表記錄,如果轉換成功則直接采用多個表的連接方式查詢。由此可見用 IN SQL 至少多了一個轉換的過程。一般的 SQL 都可以轉換成功,但對于含有分組統計等方面的 SQL 就不能轉換了。

    ?????? 推薦方案:在業務密集的 SQL 當中盡量不采用 IN 操作符。

    NOT IN操作符

    ?????? 此操作是強列推薦不使用的,因為它不能應用表的索引。

    ?????? 推薦方案:用 NOT EXISTS 或(外連接 + 判斷為空)方案代替

    <> 操作符(不等于)

    ?????? 不等于操作符是永遠不會用到索引的,因此對它的處理只會產生全表掃描。

    推薦方案:用其它相同功能的操作運算代替,如

    ?????? a<>0 改為 a>0 or a<0

    ?????? a<>’’ 改為 a>’’

    IS NULL IS NOT NULL操作(判斷字段是否為空)

    ?????? 判斷字段是否為空一般是不會應用索引的,因為 B 樹索引是不索引空值的。

    ?????? 推薦方案:

    用其它相同功能的操作運算代替,如

    ?????? a is not null 改為 a>0 a>’’ 等。

    ?????? 不允許字段為空,而用一個缺省值代替空值,如業擴申請中狀態字段不允許為空,缺省為申請。

    ?????? 建立位圖索引(有分區的表不能建,位圖索引比較難控制,如字段值太多索引會使性能下降,多人更新操作會增加數據塊鎖的現象)

    > < 操作符(大于或小于操作符)

    ?????? 大于或小于操作符一般情況下是不用調整的,因為它有索引就會采用索引查找,但有的情況下可以對它進行優化,如一個表有 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 的記錄索引。

    LIKE操作符

    LIKE 操作符可以應用通配符查詢,里面的通配符組合可能達到幾乎是任意的查詢,但是如果用得不好則會產生性能上的問題,如 LIKE ‘%5400%’ 這種查詢不會引用索引,而 LIKE ‘X5400%’ 則會引用范圍索引。一個實際例子:用 YW_YHJBQK 表中營業編號后面的戶標識號可來查詢營業編號 YY_BH LIKE ‘%5400%’ 這個條件會產生全表掃描,如果改成 YY_BH LIKE ’X5400%’ OR YY_BH LIKE ’B5400%’ 則會利用 YY_BH 的索引進行兩個范圍的查詢,性能肯定大大提高。

    UNION操作符

    UNION 在進行表鏈接后會篩選掉重復的記錄,所以在表鏈接后會對所產生的結果集進行排序運算,刪除重復的記錄再返回結果。實際大部分應用中是不會產生重復的記錄,最常見的是過程表與歷史表 UNION 。如:

    select * from gc_dfys

    union

    select * from ls_jg_dfys

    這個 SQL 在運行時先取出兩個表的結果,再用排序空間進行排序刪除重復的記錄,最后返回結果集,如果表數據量大的話可能會導致用磁盤進行排序。

    推薦方案:采用 UNION ALL 操作符替代 UNION ,因為 UNION ALL 操作只是簡單的將兩個結果合并后就返回。

    select * from gc_dfys

    union all

    select * from ls_jg_dfys

    SQL 書寫的影響

    同一功能同一性能不同寫法 SQL的影響

    如一個 SQL A 程序員寫的為

    ?????? Select * from zl_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 的執行頻率。

    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(銷戶標志)兩個字段都沒進行索引,所以執行的時候都是全表掃描,第一條SQLdy_dj = '1KV以下'條件在記錄集內比率為99%,而xh_bz=1的比率只為0.5%,在進行第一條SQL的時候99%條記錄都進行dy_dj及xh_bz的比較,而在進行第二條SQL的時候0.5%條記錄都進行dy_dj及xh_bz 的比較,以此可以得出第二條SQLCPU占用率明顯比第一條低。

    查詢表順序的影響

    FROM 后面的表中的列表順序會對 SQL 執行性能影響,在沒有索引及 ORACLE 沒有對表進行統計分析的情況下 ORACLE 會按表出現的順序進行鏈接,由此因為表的順序不對會產生十分耗服務器資源的數據交叉。(注:如果對表進行了統計分析, ORACLE 會自動先進小表的鏈接,再進行大表的鏈接)

    SQL語句索引的利用

    對操作符的優化(見上節)

    對條件字段的一些優化

    采用函數處理的字段不能利用索引,如:

    substr(hbs_bh,1,4)=’5400’ ,優化處理: hbs_bh like ‘5400%’

    trunc(sk_rq)=trunc(sysdate) , 優化處理:

    sk_rq>=trunc(sysdate) and sk_rq<trunc(sysdate+1)

    進行了顯式或隱式的運算的字段不能進行索引,如:

    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 字段是字符型。

    條件內包括了多個本表的字段運算時不能進行索引,如:

    ys_df>cx_df ,無法進行優化

    qc_bh||kh_bh=’5400250000’ ,優化處理: qc_bh=’5400’ and kh_bh=’250000’

    應用 ORACLE HINT(提示)處理

    提示處理是在 ORACLE 產生的 SQL 分析執行路徑不滿意的情況下要用到的。它可以對 SQL 進行以下方面的提示

    目標方面的提示:

    COST (按成本優化)

    RULE (按規則優化)

    CHOOSE (缺省)( ORACLE 自動選擇成本或規則進行優化)

    ALL_ROWS (所有的行盡快返回)

    FIRST_ROWS (第一行數據盡快返回)

    執行方法的提示:

    USE_NL (使用 NESTED LOOPS 方式聯合)

    USE_MERGE (使用 MERGE JOIN 方式聯合)

    USE_HASH (使用 HASH JOIN 方式聯合)

    索引提示:

    INDEX TABLE INDEX )(使用提示的表索引進行查詢)

    其它高級提示(如并行處理等等)

    ORACLE 的提示功能是比較強的功能,也是比較復雜的應用,并且提示只是給 ORACLE 執行的一個建議,有時如果出于成本方面的考慮 ORACLE 也可能不會按提示進行。根據實踐應用,一般不建議開發人員應用 ORACLE 提示,因為各個數據庫及服務器性能情況不一樣,很可能一個地方性能提升了,但另一個地方卻下降了, ORACLE SQL 執行分析方面已經比較成熟,如果分析執行的路徑不對首先應在數據庫結構(主要是索引)、服務器當前性能(共享內存、磁盤文件碎片)、數據庫對象(表、索引)統計信息是否正確這幾方面分析。

    posted on 2007-02-05 18:40 鴻雁 閱讀(207) 評論(0)  編輯  收藏

    主站蜘蛛池模板: 亚洲成av人片不卡无码久久| 日韩亚洲欧洲在线com91tv| 立即播放免费毛片一级| 国产专区一va亚洲v天堂| 99视频免费播放| 亚洲欧洲精品成人久久曰| 久久亚洲精品无码播放| 最近中文字幕完整免费视频ww | 啦啦啦高清视频在线观看免费| 国产精品亚洲AV三区| 久久亚洲国产午夜精品理论片| 成人免费看黄20分钟| 一级中文字幕乱码免费| 亚洲精品mv在线观看| 亚洲国产精品一区二区第一页免 | 亚洲精品色播一区二区| 亚洲中文字幕无码爆乳AV| 国产日本一线在线观看免费| 九九免费精品视频在这里| 亚洲色av性色在线观无码| 亚洲日本一区二区一本一道| 国产情侣激情在线视频免费看| 中美日韩在线网免费毛片视频 | 亚洲youwu永久无码精品| 亚洲av中文无码乱人伦在线咪咕| 毛片视频免费观看| 国产一级婬片A视频免费观看| 亚洲一本到无码av中文字幕 | 国产做国产爱免费视频| 亚洲熟女精品中文字幕| 久久精品国产精品亚洲艾 | 亚洲日本VA午夜在线电影| 亚洲爆乳无码专区| 亚洲麻豆精品国偷自产在线91| 久久久久国色AV免费看图片| 国内精品免费视频精选在线观看| 国产亚洲情侣久久精品| 亚洲精品伊人久久久久| 亚洲天天做日日做天天看| 中文字幕人成人乱码亚洲电影 | 亚洲成A人片777777|