???? SQL查詢語句的性能從一定程度上影響整個數(shù)據(jù)庫的性能。很多情況下,數(shù)據(jù)庫性能的低下差不多都是不良SQL語句所引起。而SQL語句的執(zhí)行
計劃則決定了SQL語句將會采用何種方式從數(shù)據(jù)庫提取數(shù)據(jù)并返回給客戶端,本文描述的將是如何通過EXPLAIN PLAN 獲取SQL語句執(zhí)行計劃來獲
取SQL語句的執(zhí)行計劃。
一、獲取SQL語句執(zhí)行計劃的方式
??? ?1. 使用explain plan 將執(zhí)行計劃加載到表plan_table,然后查詢該表來獲取預(yù)估的執(zhí)行計劃
??? ?2. 查詢動態(tài)性能視圖v$sql_plan,v$sql_plan_statistics,v$sql_workarea 等來獲取已緩存到庫緩存中的真實執(zhí)行計劃
???? 3. 查詢自動工作量資料庫(Automatic Workload Repository)或查詢Statspack,即從資料庫中獲取執(zhí)行計劃
??? ?4. 啟用執(zhí)行計劃跟蹤功能,即autotrace功能
???? 5. 使用PL/SQL Developer提供的獲取執(zhí)行計劃方法
???? 6. 使用Toad工具來獲取執(zhí)行計劃
?下面主要討論使用explain plan獲取執(zhí)行計劃的方法
二、explain plan工作實質(zhì)、前提及操作方法
??? ?1. 工作實質(zhì)
????? 將SQL語句預(yù)估的執(zhí)行計劃加載到表plan_table,是對表plan_table 執(zhí)行了DML操作,故不會執(zhí)行隱式提交
???? ?可以對select,insert,update,merge,delete,create table, create index,alter index等加載執(zhí)行計劃到plan_table
???? 2. 前提條件
???? ?需要先創(chuàng)建plan_table,創(chuàng)建方法:@?/rdbms/admin/utlxplan
????? 對當(dāng)前的SQL語句有執(zhí)行權(quán)限以及對依賴的對象有相應(yīng)操作的權(quán)限
???? 3. 使用方法:
?????? explain plan for select * from scott.emp where ename='SCOTT';??? --未設(shè)置標(biāo)記位
?????? explain plan set statement_id='TEST' for select * from scott.emp where ename='SCOTT'? --設(shè)置標(biāo)記位為TEST
三、實戰(zhàn)演習(xí)
?
?1.環(huán)境??
?2.創(chuàng)建測試表演示獲取執(zhí)行計劃?
?3.使用自頂向下的讀取方法獲取執(zhí)行計劃
??上面的例子的讀取方法:
?????? 執(zhí)行4.1的索引唯一掃描
????? ?將4.1的結(jié)果集返回給3.1
??? ???執(zhí)行3.2的全表掃描
???? ??將3.1和3.2步驟的結(jié)果集返回給2.1
??? ???執(zhí)行2.1的嵌套循環(huán)
???? ??返回最終結(jié)果集
????? ?注意嵌套循環(huán)的查詢方法
???? ??Oracle 從第一個行源中讀取第一行,然后和第二個行源中的所有記錄行進行比對,所有匹配的記錄放在結(jié)果集中,然后Oracle 將讀第一
??? ???個行源中的下一行。依次類推,直到第一行源中的所有行處理完畢。
?4.使用構(gòu)建樹方式查看執(zhí)行計劃
??? ??查詢結(jié)果中的order列與opt列
??? ??order
?????????? order列的指名了ID,父ID,以及執(zhí)行計劃中這一步驟的位置。
?????????? ID列標(biāo)識了這個步驟,但并沒有說明執(zhí)行的順序
????????? ?父ID表明了這個步驟中的父步驟
?????????? 位置信息說明了父ID相同的子操作的執(zhí)行順序????
????? opt
?????????? 說明當(dāng)前優(yōu)化器使用的模式
???? ?分析
?????????? 首先會從步驟3開始執(zhí)行,步驟3通過索引唯一掃描PK_EMP將得到的結(jié)果集返回給父步驟2
?????????? 步驟2根據(jù)上一子步驟3得到的rowid訪問表EMP并將結(jié)果集返回給父步驟1
?????????? 對于步驟2檢索到的每一行數(shù)據(jù),步驟1會將deptno傳遞給步驟5
?????????? 步驟5根據(jù)得到的deptno執(zhí)行索引唯一掃描并將結(jié)果集返回給步驟4
?????????? 步驟4根據(jù)步驟5得到的rowid 訪問表dept,并將結(jié)果集返回給父步驟1
?????????? 對于步驟3中剩余的行依次按上述方式將所有結(jié)果集返回給步驟1
?????????? 步驟1將獲得的最終結(jié)果集返回給步驟0,SQL完成查詢
??
????? 根據(jù)查詢返回的結(jié)果來構(gòu)建執(zhí)行計劃樹
?????????? 從ID為1的列開始,作為根節(jié)點
?????????? 尋找所有父ID為1的所有子ID,如本例為2和4,將其納入樹中
?????????? 分別尋找以2和4為父ID的所有子ID,將其納入樹中
?????????? 如此循環(huán)直到所有的ID沒有父ID
????????????? ---------------
????????????? NESTED LOOP (1)
????????????? ---------------
?????????????? -???? ?? -
???????????? -?????? ??? -??
??????????? -?????????? ?? -
?????? ---------????? ??----------
?????? EMP (2)???????? ??DEPT(4)
?????? ---------????? ??----------
?????????? -???????????? ?? -
????????? -???????????? ?? ??-
?? ---------????? ?????? ?----------
?? PK_EMP(3)????? ????? ??PK_DEPT(5)????
?? ---------???? ?????? ?----------
?5.通過Oracle 自帶的SQL語句執(zhí)行計劃
??可以通過Oracle提供的SQl語句來獲得當(dāng)前會話最后一條SQL語句的執(zhí)行計劃
???utlxpls.sql?? -->用于查看串行執(zhí)行計劃
???utlxplp.sql?? -->用于查看并行執(zhí)行計劃?
四、總結(jié):
???? 1. explain plan并不執(zhí)行當(dāng)前的SQL語句,而是根據(jù)數(shù)據(jù)字典中記錄的統(tǒng)計信息獲取最佳的執(zhí)行計劃并加載到表plan_table。
??? ?2. 由于統(tǒng)計信息,執(zhí)行環(huán)境的變化,explain plan與實際的執(zhí)行計劃可能會有差異。
??? ?3. 對于運行時將較長的SQL語句,不需要等到結(jié)果輸出即可提前獲得該SQL的執(zhí)行計劃,對于生產(chǎn)環(huán)境調(diào)試情況會減輕數(shù)據(jù)庫負荷。
??? ?4. 注意set statement_id標(biāo)識符區(qū)分大小寫。
?
?
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
