[20240313]toad gather_plan_statistics執行計劃相關問題.txt

来源:https://www.cnblogs.com/lfree/p/18071547
-Advertisement-
Play Games

在MySQL 8.0中,可以通過創建自定義哈希函數來處理VARCHAR類型的欄位,以便用作分區鍵。下麵是一個簡單的示例,演示如何在MySQL8.0中創建自定義哈希函數來處理VARCHAR類型的欄位 分區後的表效果 方法一,自定義哈希函數,失敗而告終 創建自定義哈希函數: DELIMITER // C ...


[20240313]toad gather_plan_statistics執行計劃相關問題.txt

--//自己現在已經很少使用toad,使用也是作為輔助功能,畢竟圖形界面能更快的操作顯示信息.
--//昨天遇到一個問題,自己當時沒有反映過來,浪費點時間,做一個記錄避免以後再次犯渾.
--//我一般在toad的sql編輯界面下儘可能看真實的執行計劃
--//參考:https://blog.itpub.net/267265/viewspace-2130781/=>[20161216]toad下顯示真實的執行計劃.txt
--//沒有想到看到的執行計劃統計存在一些問題,看下麵的例子:

1.環境:
SCOTT@book> @ ver1
PORT_STRING                    VERSION        BANNER
------------------------------ -------------- --------------------------------------------------------------------------------
x86_64/Linux 2.4.xx            11.2.0.4.0     Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production

2.建立例子:

create table t as select rownum id ,lpad('x',100,'x') name ,lpad('1',1) flag from dual connect by level<=1e4;
update t set flag='0' where id=1e4;
commit ;
create index i_t_flag on t(flag);

SCOTT@book> execute sys.dbms_stats.gather_table_stats ( OwnName => '',TabName => 't',Estimate_Percent => NULL,Method_Opt => 'FOR ALL COLUMNS SIZE 1 for columns flag size 4',Cascade => True ,No_Invalidate => false)
PL/SQL procedure successfully completed.

--//在flag欄位上建立直方圖.

3.測試:
--//在toad界面上輸入如下語句並執行如下:
SELECT  /*+ gather_plan_statistics */ * FROM T WHERE FLAG=:X;
--//註:加入gather_plan_statistics提示執行計劃可以顯示更多信息.

--//帶入'1'測試看看,執行計劃如下:
--//註意是字元串類型。
Plan hash value: 1601196873
---------------------------------------------------------------------------
| Id  | Operation         | Name | E-Rows |E-Bytes| Cost (%CPU)| E-Time   |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |        |       |    48 (100)|          |
|*  1 |  TABLE ACCESS FULL| T    |   5000 |   522K|    48   (0)| 00:00:01 |
---------------------------------------------------------------------------
--//你可以發現並沒有顯示完整的執行計劃統計信息,提示gather_plan_statistics沒有起作用。
--//實際上顯示是explain plan的執行計劃.

--//帶入'0'測試看看,執行計劃如下:
Plan hash value: 1601196873
--------------------------------------------------------------------------------------------------------------------
| Id  | Operation         | Name | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time   | A-Rows |   A-Time   | Buffers |
--------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |      1 |        |       |    48 (100)|          |      1 |00:00:00.01 |     160 |
|*  1 |  TABLE ACCESS FULL| T    |      1 |   5000 |   522K|    48   (0)| 00:00:01 |      1 |00:00:00.01 |     160 |
--------------------------------------------------------------------------------------------------------------------
-//看到的執行計劃不同,為什麼呢? 實際上問題在於toad執行時每次fetch 1001行。
--//:X = 0 是僅僅返回1條,執行計劃已經完成,可以顯示完整的統計信息。
--//而帶入:X = 1時,僅僅顯示前500條(實際上fetch 1001行),沒有執行完成,無法顯示完整的執行統計信息。可以拖動滾動條或者按
--//page down鍵到結尾,這樣也可以得到完整的執行計劃。

--//如果滾動到中間(實際上只要不到結尾), 看執行計劃:
Plan hash value: 1601196873
--------------------------------------------------------------------------------------------------------------------
| Id  | Operation         | Name | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time   | A-Rows |   A-Time   | Buffers |
--------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |      1 |        |       |    48 (100)|          |   1001 |00:00:00.01 |      18 |
|*  1 |  TABLE ACCESS FULL| T    |      1 |   5000 |   522K|    48   (0)| 00:00:01 |   1001 |00:00:00.01 |      18 |
--------------------------------------------------------------------------------------------------------------------
--//看到A-ROWS=1001.也就是第1次fetch的數量,也就是以後在toad下看這類執行計劃註意,這樣看到的執行計劃的統計信息可能不真實!!
--//如果按page down鍵到結尾再看執行計劃:
Plan hash value: 1601196873
--------------------------------------------------------------------------------------------------------------------
| Id  | Operation         | Name | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time   | A-Rows |   A-Time   | Buffers |
--------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |      1 |        |       |    48 (100)|          |   9999 |00:00:00.01 |     168 |
|*  1 |  TABLE ACCESS FULL| T    |      1 |   5000 |   522K|    48   (0)| 00:00:01 |   9999 |00:00:00.01 |     168 |
--------------------------------------------------------------------------------------------------------------------

--//如果在sql編輯界面上打開auto trace,全部結果fetch完成就不會出現上面看到的情況了。
--//再次帶入'1'測試看看,執行計劃如下:
Plan hash value: 1601196873
--------------------------------------------------------------------------------------------------------------------
| Id  | Operation         | Name | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time   | A-Rows |   A-Time   | Buffers |
--------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |      1 |        |       |    48 (100)|          |   9999 |00:00:00.01 |     168 |
|*  1 |  TABLE ACCESS FULL| T    |      1 |   5000 |   522K|    48   (0)| 00:00:01 |   9999 |00:00:00.01 |     168 |
--------------------------------------------------------------------------------------------------------------------

4.繼續測試:
--//關閉auto trace。
--//再次帶入'1'測試看看,執行計劃如下:
Plan hash value: 1601196873
--------------------------------------------------------------------------------------------------------------------
| Id  | Operation         | Name | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time   | A-Rows |   A-Time   | Buffers |
--------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |      1 |        |       |    48 (100)|          |   9999 |00:00:00.01 |     168 |
|*  1 |  TABLE ACCESS FULL| T    |      1 |   5000 |   522K|    48   (0)| 00:00:01 |   9999 |00:00:00.01 |     168 |
--------------------------------------------------------------------------------------------------------------------

--//再次帶入'1'測試看看,執行計劃如下:
Plan hash value: 1601196873
--------------------------------------------------------------------------------------------------------------------
| Id  | Operation         | Name | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time   | A-Rows |   A-Time   | Buffers |
--------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |      1 |        |       |    48 (100)|          |   1001 |00:00:00.01 |      18 |
|*  1 |  TABLE ACCESS FULL| T    |      1 |   5000 |   522K|    48   (0)| 00:00:01 |   1001 |00:00:00.01 |      18 |
--------------------------------------------------------------------------------------------------------------------
--//註:當時馬上看執行計劃,理論講應該沒有A-Rows之類的統計,本來以為會顯示explain plan的執行計劃,但是看到的卻是
--//A-Rows=1001的情況,我猜測可能是使用dbms_xplan.display_cursor,format加入last的緣故.

--//開始我很困惑,實際上這樣第1次執行看到的是前1次的執行計劃統計信息。

--//使用SQL Tracker跟蹤發現,toad執行如下:
select * from table(dbms_xplan.display_cursor(sql_id => '7pnr0krspk166', cursor_child_no => null, format => 'ALL,
ALLSTATS, LAST, ROWS, BYTES, COST, OUTLINE, PARTITION, PARALLEL, PEEKED_BINDS, PREDICATE, PROJECTION, ALIAS, REMOTE,
NOTE'))

--//加入有參數last,顯示參數我基本全部選上。
--//而第2次執行,因為前面有記錄這個統計信息,這樣就有顯示,雖然不准確。當然這些是我的猜測!!

--//總之,在toad下註意這個細節,建議優化調試sql語句時打開auto trace,這樣看執行計劃的統計信息比較準確,不容易出現誤判。

5.另外的問題註意:
--//你可以註意一個細節,toad下無論帶入'0'還是'1'選擇的執行計劃都是全表掃描,E-Rows=5000並沒有採用直方圖的結果,也就是總記
--//錄的50%.
--//即使小量修改sql語句,sql_id不同,導致重新分析sql語句,第1次帶入參數'0',執行計劃也是選擇全表掃描。
--//如果仔細看Outline Data部分:
/*+
      BEGIN_OUTLINE_DATA
      IGNORE_OPTIM_EMBEDDED_HINTS
      OPTIMIZER_FEATURES_ENABLE('11.2.0.4')
      DB_VERSION('11.2.0.4')
      OPT_PARAM('_optim_peek_user_binds' 'false')
      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      ALL_ROWS
      OUTLINE_LEAF(@"SEL$1")
      FULL(@"SEL$1" "T"@"SEL$1")
      END_OUTLINE_DATA
  */

--//不知道為什麼toad關閉了綁定變數peek。而且我不知道怎麼打開,使用toad的版本號12.6.0.53,只有toad 9.X版本正常的.
--//這樣使得在toad調試sql語句涉及到這方面相關問題時要小心,而且導致BIND_AWARE提示無效。

SELECT   /*+ gather_plan_statistics BIND_AWARE OPT_PARAM('_optim_peek_user_binds' 'true') */ * FROM T WHERE FLAG=:X;
Plan hash value: 1601196873
 
--------------------------------------------------------------------------------------------------------------------
| Id  | Operation         | Name | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time   | A-Rows |   A-Time   | Buffers |
--------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |      1 |        |       |    48 (100)|          |      1 |00:00:00.01 |     160 |
|*  1 |  TABLE ACCESS FULL| T    |      1 |   5000 |   522K|    48   (0)| 00:00:01 |      1 |00:00:00.01 |     160 |
--------------------------------------------------------------------------------------------------------------------
--//還是全表掃描。
 
6.sqlplus下測試:

SCOTT@book> variable x varchar2(32) ;
SCOTT@book> exec :x :='0';
PL/SQL procedure successfully completed.

SCOTT@book> SELECT   /*+ gather_plan_statistics  */ * FROM T WHERE FLAG=:X;
        ID NAME                                     F
---------- ---------------------------------------- -
     10000 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 0
           xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
           xxxxxxxxxxxxxxxxxxxx


SCOTT@book> @ dpc '' '' ''
PLAN_TABLE_OUTPUT
-------------------------------------
SQL_ID  8s7vwp7ykv52x, child number 1
-------------------------------------
SELECT   /*+ gather_plan_statistics  */ * FROM T WHERE FLAG=:X
Plan hash value: 120143814
----------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                   | Name     | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time   | A-Rows |   A-Time   | Buffers |
----------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |          |      1 |        |       |     2 (100)|          |      1 |00:00:00.01 |       4 |
|   1 |  TABLE ACCESS BY INDEX ROWID| T        |      1 |      1 |   107 |     2   (0)| 00:00:01 |      1 |00:00:00.01 |       4 |
|*  2 |   INDEX RANGE SCAN          | I_T_FLAG |      1 |      1 |       |     1   (0)| 00:00:01 |      1 |00:00:00.01 |       3 |
----------------------------------------------------------------------------------------------------------------------------------
Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------
   1 - SEL$1 / T@SEL$1
   2 - SEL$1 / T@SEL$1
Peeked Binds (identified by position):
--------------------------------------
   1 - (VARCHAR2(30), CSID=852): '0'
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("FLAG"=:X)
--//建立新的子游標,child number=1,可以使用I_T_FLAG索引。

7.總結:
--//註意toad下調試優化sql語句時註意這個細節,避免以後在這個方面浪費時間。
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Linux系統提供了許多命令來分析系統性能。以下是一些常用的Linux系統性能分析命令: top:實時監視系統的運行狀態和進程信息,包括CPU使用率、記憶體使用情況、進程狀態等。 實例:直接在終端中輸入top,即可實時查看系統進程狀態及資源占用情況。 htop:類似於top,但提供更友好的界面和交互, ...
  • 一、下載Nginx安裝包 Nginx官網下載地址 根據需求選擇自己需要的版本下載後上傳至伺服器(路徑自行決定)。 如果伺服器有外網,可以直接在伺服器上下載。 wget -c https://nginx.org/download/nginx-1.24.0.tar.gz 二、安裝Nginx 解壓安裝包 ...
  • 引言 關係資料庫中的關係滿足一定要求的,滿足不同程度要求的為不同的範式,共有6種範式。 滿足最低要求的叫第一範式,簡稱 1NF;在第一範式的基礎上滿足進一步要求的稱為第二範式,簡稱 2NF; 其餘範式以此類推。 對於各種範式之間有如下關係: 5NF ∈ 4NF ∈ BCNF ∈ 3NF ∈ 2NF ...
  • auth_delay 讓伺服器在報告身份驗證失敗前短暫暫停,以增加對資料庫密碼進行暴力破解的難度。需要註意的是,這對阻止拒絕服務攻擊毫無幫助,甚至可能加劇攻擊,因為在報告身份驗證失敗前等待的進程仍會占用連接。 要使用這個模塊必須要在 postgresql.conf 中配置參數 shared_prel ...
  • 本文分享自華為雲社區《GaussDB資料庫的索引管理》,作者: Gauss松鼠會小助手2。 一、引言 GaussDB資料庫是華為公司傾力打造的自研企業級分散式關係型資料庫,索引的設計和管理對於提高查詢性能至關重要。下麵將通過實際例子深入研究GaussDB資料庫的索引管理。 二、GaussDB資料庫中 ...
  • adminpack 提供了大量支持功能,pgAdmin 和其他管理工具可以使用這些功能提供額外功能,例如遠程管理伺服器日誌文件。預設情況下,只有資料庫超級用戶才能使用所有這些功能,但其他用戶也可以使用 GRANT 命令使用這些功能。 我們先來看一下他支持的函數,可以通過 \dx+ adminpack ...
  • 在我們講解這個案例前,我們先來瞭解/預熱一下SQL Server的兩個概念:鍵查找(key lookup)和RID查找(RID lookup),通常,當查詢優化器使用非聚集索引進行查找時,如果所選擇的列或查詢條件中的列只部分包含在使用的非聚集索引和聚集索引中時,就需要一個查找(lookup)來檢索其 ...
  • 支持事務安全表(ACID),支持行鎖定和外鍵; MySQL事務的ACID特性是確保數據準確性和可靠性的基本原則,包括**原子性(Atomicity)、一致性(Consistency)、隔離性(Isolation)和持久性(Durability)**。具體如下: 1. **原子性(Atomicity) ...
一周排行
    -Advertisement-
    Play Games
  • .Net8.0 Blazor Hybird 桌面端 (WPF/Winform) 實測可以完整運行在 win7sp1/win10/win11. 如果用其他工具打包,還可以運行在mac/linux下, 傳送門BlazorHybrid 發佈為無依賴包方式 安裝 WebView2Runtime 1.57 M ...
  • 目錄前言PostgreSql安裝測試額外Nuget安裝Person.cs模擬運行Navicate連postgresql解決方案Garnet為什麼要選擇Garnet而不是RedisRedis不再開源Windows版的Redis是由微軟維護的Windows Redis版本老舊,後續可能不再更新Garne ...
  • C#TMS系統代碼-聯表報表學習 領導被裁了之後很快就有人上任了,幾乎是無縫銜接,很難讓我不想到這早就決定好了。我的職責沒有任何變化。感受下來這個系統封裝程度很高,我只要會調用方法就行。這個系統交付之後不會有太多問題,更多應該是做小需求,有大的開發任務應該也是第二期的事,嗯?怎麼感覺我變成運維了?而 ...
  • 我在隨筆《EAV模型(實體-屬性-值)的設計和低代碼的處理方案(1)》中介紹了一些基本的EAV模型設計知識和基於Winform場景下低代碼(或者說無代碼)的一些實現思路,在本篇隨筆中,我們來分析一下這種針對通用業務,且只需定義就能構建業務模塊存儲和界面的解決方案,其中的數據查詢處理的操作。 ...
  • 對某個遠程伺服器啟用和設置NTP服務(Windows系統) 打開註冊表 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\TimeProviders\NtpServer 將 Enabled 的值設置為 1,這將啟用NTP伺服器功 ...
  • title: Django信號與擴展:深入理解與實踐 date: 2024/5/15 22:40:52 updated: 2024/5/15 22:40:52 categories: 後端開發 tags: Django 信號 松耦合 觀察者 擴展 安全 性能 第一部分:Django信號基礎 Djan ...
  • 使用xadmin2遇到的問題&解決 環境配置: 使用的模塊版本: 關聯的包 Django 3.2.15 mysqlclient 2.2.4 xadmin 2.0.1 django-crispy-forms >= 1.6.0 django-import-export >= 0.5.1 django-r ...
  • 今天我打算整點兒不一樣的內容,通過之前學習的TransformerMap和LazyMap鏈,想搞點不一樣的,所以我關註了另外一條鏈DefaultedMap鏈,主要調用鏈為: 調用鏈詳細描述: ObjectInputStream.readObject() DefaultedMap.readObject ...
  • 後端應用級開發者該如何擁抱 AI GC?就是在這樣的一個大的浪潮下,我們的傳統的應用級開發者。我們該如何選擇職業或者是如何去快速轉型,跟上這樣的一個行業的一個浪潮? 0 AI金字塔模型 越往上它的整個難度就是職業機會也好,或者說是整個的這個運作也好,它的難度會越大,然後越往下機會就會越多,所以這是一 ...
  • @Autowired是Spring框架提供的註解,@Resource是Java EE 5規範提供的註解。 @Autowired預設按照類型自動裝配,而@Resource預設按照名稱自動裝配。 @Autowired支持@Qualifier註解來指定裝配哪一個具有相同類型的bean,而@Resourc... ...