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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

SQL的执行计划

發布時間:2023/11/30 数据库 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SQL的执行计划 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

SQL的執行計劃實際代表了目標SQL在Oracle數據庫內部的具體執行步驟,作為調優,只有知道了優化器選擇的執行計劃是否為當前情形下最優的執行計劃,才能夠知道下一步往什么方向。


執行計劃的定義:執行目標SQL的所有步驟的組合


我們首先列出查看執行計劃的一些常用方法:

1. explain plan命令

PL/SQL Developer中通過快捷鍵F5就可以查看目標SQL的執行計劃了。但其實按下F5后,實際后臺調用的就是explain plan命令,相當于封裝了該命令。

explain plan使用方法:

(1) 執行explain plan for + SQL

(2) 執行select * from table(dbms_xplan.display);

實驗表準備:

SQL> desc test1;
?Name ?Null ? ? ? ? ? Type
?----------------------------------------- -------- ----------------------------
?T1ID ? ?NOT NULL NUMBER(38)
?T1V ? ? ? ? ? ? ? ? ? ? ? VARCHAR2(10)

SQL> desc test2;
?Name ?Null ? ? ? ? ? Type
?----------------------------------------- -------- ----------------------------
?T2ID ? ?NOT NULL NUMBER(38)
?T2V ? ? ? ? ? ? ? ? ? ? ? VARCHAR2(10)

實驗

SQL> set linesize 100

SQL> explain plan for select t1id, t1v, t2id, t2v from test1, test2 where test1.t1id = test2.t2id;

Explained.


第一步使用explain plan對目標SQL進行了explain,第二步使用select * from table(dbms_xplan.display)語句展示出該SQL的執行計劃。

這里test2作為驅動表,進行了全表掃描,test1作為被驅動表,由于其包含主鍵,所以用的是索引全掃描。左側ID帶*號的第四步操作,表示有謂詞條件,這里可以看到既使用了主鍵索引(access),又使用了過濾條件(filter)。


2. DBMS_XPLAN包

(1) select * from table(dbms_xplan.display);--上面以說明。

(2)?select * from table(dbms_xplan.display_cursor(null, null, 'advanced'));

(3)?select * from table(dbms_xplan.display_cursor('sql_id/hash_value', child_cursor_number, 'advanced'));

(4)?select * from table(dbms_xplan.display_awr('sql_id'));


(2)?select * from table(dbms_xplan.display_cursor(null, null, 'advanced'));

主要用于SQLPLUS中查看剛執行過SQL的執行計劃。首先第三個參數可以選擇'advanced':





接下來,第三個參數使用'all':




可以看出'advanced'記錄的信息要比'all’多,主要就是多一個Outline Data。Outline Data主要是執行SQL時用于固定執行計劃的內部HINT組合,可以將這部分內容摘出來加到目標SQL中以固定其執行計劃


(3)?select * from table(dbms_xplan.display_cursor('sql_id/hash_value', child_cursor_number, 'advanced'));

其中第一個參數可以輸入SQL的sql_id或hash value,方法就是如果執行的SQL仍在庫緩存中,則可以使用V$SQL查詢:


其中,使用@dbsnake大牛的SQL可以知道SQL_ID和HASH_VALUE的一一對應關系:


隱藏問題1:

這里的截圖可能有點問題,結果并不準確,問題就出在這個SQL中使用的算法中,在另一篇博文中會仔細說明這個問題

使用:

SQL>?select * from table(dbms_xplan.display_cursor('1p2fk2v00c865', 0, 'advanced'));

select * from table(dbms_xplan.display_cursor('3221627077', 0, 'advanced'));

就可以查出對應這條SQL的執行計劃,內容同(2)中的'advanced',這就不展示了。

注意這還有第二個參數child_cursor_number,指的是子游標編號,如果未生成新的子游標,則此處寫的是0。

(2)和(3)的結論相近,區別就是(2)只是針對最近一次執行SQL查看執行計劃,(3)可以針對仍在庫緩存中的任意一次SQL查看執行計劃


(4)?select * from table(dbms_xplan.display_awr('sql_id'));

(1)是使用explain plan for +SQL作為前提,(2)和(3)的前提則是SQL的執行計劃還在共享池中,具體講是在庫緩存中。如果已經被age out交換出共享池,則不能用這兩種方法了。若該SQL的執行計劃被采集到AWR庫中,則可以用(4)來查詢歷史執行計劃。

隱藏問題2:

實驗這部分內容發現使用select * from table(dbms_xplan.display_awr('sql_id'));并沒有結果,@黃瑋老師說有可能是AWR收集的是top的SQL,有可能測試用的SQL不是most intensive SQL,但我是用alter system flush shared_pool后執行的手工采集快照,還是未被AWR抓到,比較奇怪的問題,這個也會在另一篇博文中仔細說明。


創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的SQL的执行计划的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。