日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

高级SQL优化(二) ——《12年资深DBA教你Oracle开发与优化——性能优化部分》

發(fā)布時(shí)間:2025/7/25 数据库 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 高级SQL优化(二) ——《12年资深DBA教你Oracle开发与优化——性能优化部分》 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

目錄:

Oracle數(shù)據(jù)完整性和鎖機(jī)制? 索引及優(yōu)化之表分析? 表分析、約束及表間關(guān)系? Oracle體系結(jié)構(gòu)1 Oracle體系結(jié)構(gòu)2? 海量數(shù)據(jù)庫及分區(qū)1? 海量數(shù)據(jù)庫及分區(qū)2? 海量數(shù)據(jù)庫及分區(qū)3? 海量數(shù)據(jù)庫及分區(qū)4? 高級(jí)SQL優(yōu)化(一)?? 高級(jí)SQL優(yōu)化(二)?? 高級(jí)SQL優(yōu)化(三) 常用優(yōu)化工具? PPT和源碼下載:???http://***/forum/posts/list/6365.html 配套視頻課程 Oracle性能優(yōu)化?http://***/product/601? 海量數(shù)據(jù)庫和高級(jí)SQL優(yōu)化?http://***/product/602 充分利用索引 索引的限制 1. 索引對(duì)不等號(hào)和NOT的限制 如果WHERE條件中出現(xiàn)!=或者<>,即使該列建立了索引,則該索引也不會(huì)被使用;如果不恰當(dāng)?shù)氖褂昧薔OT,則索引也不會(huì)被使用。 Oracle 10g起,在基于CBO的優(yōu)化器模式下Oralce會(huì)進(jìn)行自動(dòng)優(yōu)化,但在基于RBO(基于規(guī)則)的優(yōu)化器模式下,依然保持此規(guī)則。 1. 索引對(duì)不等號(hào)和NOT的限制 RBO模式下,執(zhí)行計(jì)劃如下: ? 1. 索引對(duì)不等號(hào)和NOT的限制 RBO模式下,執(zhí)行情況如下: 此時(shí)使用變通寫法的耗費(fèi)為:0.407/2.187=1.60%! 1. 索引對(duì)不等號(hào)和NOT的限制 CBO模式下,執(zhí)行情況如下: 此時(shí)使用變通寫法的耗費(fèi)節(jié)約不到0.03秒,但依然更優(yōu),故此推薦此種變通寫法,再看此時(shí)使用NOT: 1. 索引對(duì)不等號(hào)和NOT的限制 CBO模式下,在JYJE列的索引上使用NOT: ? 為使用<>的:0.156/0.329=47.42%!為變通寫法的使用0.156/0.297=52.53%! 此這種寫法最優(yōu)! 1. 索引對(duì)不等號(hào)和NOT的限制 一般,WHERE條件中,如果索引列是字符列,使用NOT往往也不會(huì)使用索引: 結(jié)論:如果索引列是數(shù)字,則對(duì)于不等號(hào)的處理可以變更為NOT的方式或者(大于 OR 小于)的方式① ;對(duì)于確實(shí)無法不使用不等號(hào)的方式,可以使用默認(rèn)值② ;如果可以建立位圖索引則使用位圖索引③ ;否則可以考慮使用分區(qū)等方法進(jìn)行優(yōu)化④ ,具體是情況而定。 2. 索引對(duì)IS NULL的限制 一般來說,如果WHERE子句基于的列是可空的列,且其建立了索引,如果使用了IS NULL,由于NULL的列本身不包含在索引中,因此無法利用索引。 所以一般對(duì)要建立索引的列不要設(shè)置為可空,如果確實(shí)含有空值,建議使用默認(rèn)值代替空值,具體參見前面章節(jié)“SQL優(yōu)化技巧”部分的“使用默認(rèn)值”。 3. 索引對(duì)函數(shù)的限制 基于索引IDX_BIGTAB_OBJECTNAME,執(zhí)行情況如下: ? 執(zhí)行計(jì)劃情況如下: 這是因?yàn)樵撍饕浅R?guī)b-tree索引,對(duì)該列在WHERE子句中使用了函數(shù),則不能使用索引。因此,對(duì)在WHERE子句中經(jīng)常要使用函數(shù)時(shí),應(yīng)該建立基于函數(shù)的索引,且 只有當(dāng)查詢語句包含該函數(shù)或者表達(dá)式時(shí),基于函數(shù)的索引才會(huì)被調(diào) 。詳情請(qǐng)參見索引部分的理論講解! 創(chuàng)建并使用函數(shù)索引: ? ? 創(chuàng)建并使用函數(shù)索引: 此時(shí)使用基于函數(shù)的索引效率是原來的2.782/0.188=14.78!唄! 4. 索引對(duì)不匹配數(shù)據(jù)類型的限制 先看執(zhí)行情況: ? 不匹配的類型執(zhí)行的時(shí)間是匹配的類型的 2.187/0.266=8.2 倍! 再看執(zhí)行計(jì)劃: 原因分析: 因?yàn)锳CCOUNT_TRADE表的字段YKKH是CHAR,因此在對(duì)其指定的值是數(shù)字時(shí),Oracle雖然能隱式的執(zhí)行數(shù)字和字符的轉(zhuǎn)換,但不會(huì)調(diào)用其索引。而當(dāng)對(duì)其指定是字符時(shí),則不存在此問題,索引可以調(diào)用。 注意:因?yàn)閿?shù)據(jù)類型的不匹配和Oracle對(duì)數(shù)據(jù)類型的隱式轉(zhuǎn)換,此種類型的低效代碼在任何項(xiàng)目中均可能因?yàn)榇笠舛嬖?#xff0c;因此建議開發(fā)人員和管理人員要定期抽查相應(yīng)的代碼,以杜絕此類低效代碼! 索引類型總結(jié)
類型 ,描述
b-tree索引 最常最多使用的索引,其樹結(jié)構(gòu)與二叉樹比較類似,根據(jù)ROWID快速定位所訪問的行
bitmap索引 使用位圖來管理與數(shù)據(jù)行的對(duì)應(yīng)關(guān)系,適用于基數(shù)比較少的列
降序索引 降序索引在葉子節(jié)點(diǎn)中的存儲(chǔ)從左到右是按照從大到小排序的;一般是針對(duì)逆向排序較多的查詢時(shí)才使用該類型索引
函數(shù)索引 針對(duì)要頻繁對(duì)列使用函數(shù)的索引,只有當(dāng)查詢語句包含該函數(shù)或者表達(dá)式時(shí),基于函數(shù)的索引才會(huì)被調(diào)用
反轉(zhuǎn)索引 反轉(zhuǎn)了b*tree索引碼中的字節(jié),使索引條目分配更均勻,多用于并行服務(wù)器環(huán)境下,用于減少索引的競(jìng)爭(zhēng)
分區(qū)索引 分區(qū)表的索引,又包括本地分區(qū)索引(本地前綴分區(qū)索引和本地非前綴分區(qū)索引)和全局索引,一般建議使用本地分區(qū)索引,因其與基表具有良好的數(shù)據(jù)均衡性和可維護(hù)性
? 訪問路徑 1. 全表掃描 ?全表掃描(FULL TABLE SCANS)時(shí)所有行、所有數(shù)據(jù)塊均會(huì)被讀到,是 效率最 的一種,一般會(huì)在表 缺少索引讀取大量數(shù)據(jù)訪問小表高并發(fā)時(shí)發(fā)生。 ? ? 2. ROWID掃描 ? ROWID掃描(ROWID SCANS)是通過ROWID中數(shù)據(jù)文件和塊位置訪問數(shù)據(jù)行。一般作為訪問索引后的第二步,如果訪問的列全部包含在索引中,則不會(huì)執(zhí)行ROWID掃描。 ? ??作為索引訪問后的第二步: 訪問的列全部在索引中不再執(zhí)行ROWID掃描? ? 3. 索引掃描 ? 索引掃描(INDEX SCANS)包含全索引掃描(full index scan、FIS)、快速全索引掃描(fast full index scan、FFIS)、索引范圍掃描(index range scan)、索引唯一掃描 (index unique scan)、索引跳躍式掃描 (index skip scan)、位圖索引掃描(bitmap index scan), 其中前5種在本系列課程的索引章 節(jié)部分已經(jīng)講解了其理論和示例。位圖索引示例如下: ? 3. 索引掃描
類型 方式 發(fā)生條件
1.FULL INDEX SCANS 逐一讀取索引中的所有塊,由于索引中數(shù)據(jù)已按索引鍵排序,因此會(huì)忽略掉排序 1.ORDER BY中的列全部在該索引中時(shí)
2.ORDER BY中列的順序滿足索引中前導(dǎo)列的順序時(shí)
3.使用GROUP BY且該子句中的列在索引中時(shí)
2.FAST FULL INDEX SCANS 只掃描索引中的數(shù)據(jù),不會(huì)掃描表中的數(shù)據(jù);由于索引中數(shù)據(jù)未按索引鍵排序,因此不能忽略掉排序 當(dāng)同時(shí)滿足下列條件是,Oracle用FFIS替代FIS:
1.查詢的所有列均包含在索引中
2.索引中的列至少一個(gè)具有not null約束
3.INDEX RANGE SCANS 訪問選擇性數(shù)據(jù)最常用的掃描方式;按順序的對(duì)某個(gè)索引進(jìn)行掃描,返回?cái)?shù)據(jù)是升序排列的,可以使用唯一索引和非唯一索引;如果對(duì)索引列使用ORDER BY/GROUP BY則可省略排序 1.在唯一索引上使用范圍操作符(>、<、>=、<=、<>、BETWEEN)
2.在組合索引上使用部分列進(jìn)行查詢,導(dǎo)致查出多行
4.INDEX UNIQUE SCANS 掃描唯一索引或主鍵,要么返回一行數(shù)據(jù)要么返回0行數(shù)據(jù) 1.當(dāng)使用唯一索引時(shí)
2.當(dāng)使用主鍵時(shí)
5.INDEX SKIP SCANS 其實(shí)質(zhì)是將索引分解成多個(gè)小的子索引來提高效率,系從9i開始引入 復(fù)合索引中前導(dǎo)列的取值是枚舉的從而可以分拆為多個(gè)子索引,并且查詢條件中不含前導(dǎo)列時(shí)
為了 加深鞏固前面的知識(shí),本處對(duì)前五種索引掃描復(fù)習(xí)總結(jié)如下: (1).全索引掃描 逐一讀取索引中的所有塊,由于索引中數(shù)據(jù)已按索引鍵排序,因此會(huì)忽略掉排序,可能發(fā)生的情況如下: A. ORDER BY中的列全部在某個(gè)索引中 全部在某個(gè)索引中: ? (1).全索引掃描 B. ORDER BY中列的順序滿足索引中前導(dǎo)列的順序時(shí) 下面分別是滿足和不滿足前導(dǎo)列順序時(shí): C. 使用GROUP BY且該子句中的列在索引中時(shí) (2).快速全索引掃描 只掃描索引中的數(shù)據(jù),不會(huì)掃描表中的數(shù)據(jù);由于索引中數(shù)據(jù)未按索引鍵排序,因此不能忽略掉排序。當(dāng)同時(shí)滿足下列條件時(shí),Oracle用FFIS替代FIS或FTS: 1.查詢的所有列均包含在索引中 2.索引中的列至少一個(gè)具有not null約束(10g開始的,原低版本的系統(tǒng)中為查詢的列中不包含任何null值) 全部列均在索引中: ? 有列不在索引中: 刪除該索引,創(chuàng)建新索引,兩個(gè)列均為可空: 此時(shí)即使全部列在該索引中, ?也不會(huì)發(fā)生FFIS 索引范圍掃描是訪問選擇性數(shù)據(jù)最常用的掃描方式;按順序的對(duì)某個(gè)索引進(jìn)行掃描,返回?cái)?shù)據(jù)是升序排列的,可以使用唯一索引和非唯一索引;如果對(duì)索引列使用ORDER BY/GROUP BY則可省略排序。 下列情形中會(huì)發(fā)生索引范圍掃描: A.在唯一索引上使用范圍操作符(>、<、>=、<=、<>、BETWEEN) B.在組合索引上使用部分列進(jìn)行查詢,導(dǎo)致查出多行 示例請(qǐng)參考本系列課程的索引章節(jié)部分 (4).索引唯一掃描 當(dāng)使用主鍵或唯一索引時(shí)發(fā)生。 示例請(qǐng)參考本系列課程的索引章節(jié)部分。 (5).索引跳躍掃描 復(fù)合索引中前導(dǎo)列的取值是枚舉的從而可以分拆為多個(gè)子索引,并且查詢條件中不含前導(dǎo)列時(shí)。示例如下: create table customers as select * from sh.customers; CREATE INDEX customers_gender_email ON customers (cust_gender, cust_email); (5).索引跳躍掃描 沒進(jìn)行表分析前: 進(jìn)行表分后: analyze table customers compute statistics; ? 何時(shí)需要索引 一般地,對(duì)于從表的總行中的大部分查詢只查詢不到10%數(shù)據(jù)(有的稱為2%-4%)的表,可以考慮創(chuàng)建索引。一般考慮的索引的原則包括: l對(duì)于經(jīng)常以查詢關(guān)鍵字為基礎(chǔ)的表,并且該表中的數(shù)據(jù)行是均勻分布的 l以查詢關(guān)鍵字為基礎(chǔ),表中的數(shù)據(jù)行隨機(jī)排序 l表中包含的列數(shù)相對(duì)比較少(僅僅是相對(duì),需要根據(jù)實(shí)際情況確定) l表中的大多數(shù)查詢都包含相對(duì)簡(jiǎn)單的WHERE子句 l表的記錄數(shù)比較少的,不建議使用索引,如數(shù)據(jù)不超過1萬行的表不要建立索 ? 為索引選擇列和表達(dá)式 一般遵循的原則包括: l經(jīng)常在WHERE子句中使用的列 lSQL語句中經(jīng)常用于表之間連接的列 l重復(fù)性少(可選擇性高)的關(guān)鍵字,如主鍵 l不宜將經(jīng)常UPDATE的列作為索引列 l不宜將經(jīng)常在WHERE子句中使用,但與函數(shù)或操作符相結(jié)合的列作為索引列 l對(duì)于取值較少的列,應(yīng)考慮建立位圖索引,而不應(yīng)該采用B樹索引 l如果經(jīng)常訪問的列上要使用函數(shù),應(yīng)使用基于函數(shù)的索引 本處舉例說明取值較少的列使用bitmap索引和b-tree的對(duì)比分析,B-tree時(shí): ? ? bitmap時(shí): ? 使用復(fù)合索引 多個(gè)列聯(lián)合起來組成的索引稱為復(fù)合索引、或聯(lián)合索引或者組合索引,往往聯(lián)合索引比單個(gè)索引具有更好的性能。創(chuàng)建聯(lián)合索引一般遵循的原則包括: l經(jīng)常在WHERE子句中使用的列且這些列之間使用AND連接 l查詢條件可能包括n個(gè)列的AND關(guān)系,而大多數(shù)情況下使用m個(gè)列是(n>m),應(yīng)該考慮復(fù)合索引,且n個(gè)列為前導(dǎo)列 l某幾個(gè)列聯(lián)合起來能夠組成唯一索引,應(yīng)堅(jiān)決建立聯(lián)合唯一索引 l復(fù)合索引中,建議至少一個(gè)不能為null,且如果可能盡量將只是存在null的列對(duì)其null值采用其它默認(rèn)值代替 本處舉例說明Where中包含AND時(shí)使用多個(gè)索引性能低于聯(lián)合索引的示例,使用多個(gè)索引時(shí): ? 本處舉例說明Where中包含AND是使用多個(gè)索引性能低于聯(lián)合索引的示例,使用復(fù)合索引時(shí): ? ?結(jié)論:
項(xiàng)目 多個(gè)索引 復(fù)合索引 復(fù)合索引是多個(gè)索引的
一、執(zhí)行時(shí)間 0.281 0.11 39.15%
二、執(zhí)行計(jì)劃 ???
1.總耗費(fèi) 1658 464 27.99%
2.I/O耗費(fèi) 1562 462 29.58%
3.時(shí)間 19 6 31.58%
可見,此時(shí)復(fù)合索引是多個(gè)索引的效率的 四倍以上! 監(jiān)視索引的使用情況 u正確合適的索引是查詢優(yōu)化性能的首選 u索引是表的索引列排序后的小型化拷貝,會(huì)增加存儲(chǔ)開銷,因此會(huì)帶來Insert、Update、Delete的額外開銷 u一個(gè)表可以有一個(gè)索引,也可以有多個(gè)索引,往往過多的索引或不恰當(dāng)?shù)乃饕龓淼呢?fù)面性能更多 u表索引的設(shè)計(jì)初衷,往往在40%甚至更高的情況下與最終的實(shí)際使用情況不符合,此舉視設(shè)計(jì)人員對(duì)業(yè)務(wù)和Oracle的理解不同而不同 u監(jiān)視索引的實(shí)際使用情況,尤其在表具有多個(gè)索引的情況下,就顯得尤為重要,對(duì)經(jīng)常不使用的索引采用合并為復(fù)合索引或刪除是優(yōu)化的工作之一 示例如下: 1.創(chuàng)建索引 2.啟用所以監(jiān)視 3.執(zhí)行SQL ? 4.查看索引使用情況 ? 我們可以根據(jù)一個(gè)持續(xù)時(shí)間的對(duì)索引的監(jiān)控結(jié)果決定如何合并及刪除不恰當(dāng)?shù)乃饕? 5.停止監(jiān)視索引 ?

轉(zhuǎn)載于:https://www.cnblogs.com/liuzhuqing/archive/2013/02/04/7480629.html

總結(jié)

以上是生活随笔為你收集整理的高级SQL优化(二) ——《12年资深DBA教你Oracle开发与优化——性能优化部分》的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。