SQL Server 執行計劃利用統計信息對數據行的預估原理二(為什么復合索引列順序會影響到執行計劃對數據行的預估)...

?

本文出處:http://www.cnblogs.com/wy123/p/6008477.html?

  關于統計信息對數據行數做預估,之前寫過對非相關列(單獨或者單獨的索引列)進行預估時候的算法,參考這里。
  今天來寫一下統計信息對于復合索引在預估時候的計算方法和潛在問題。
  本文原形來自于是個實際業務問題,某SQL在利用一個符合索引做查詢的時候,發現始終會出現預估誤差較大的情況,
  而改變復合索引的列順序,這個預估行數的誤差會發生變化,
  也就是說,Create index idx_index1 ON TableName(col1,col2)與Create index idx_index2 on TableName(col2,col1)
  用完全一樣的的查詢條件做查詢,兩個索引的執行計劃對其預估的行數是不一樣的
  究其原因在哪里呢?

  

  先造一個測試環境:

CREATE TABLE TestStatistics
(COL1 INT IDENTITY(1,1)  ,COL2 INT                ,COL3 DATETIME           ,COL4 VARCHAR(50)            
)
GOINSERT INTO TestStatistics VALUES (RAND()*10,CAST(GETDATE()-RAND()*300 AS date),NEWID())
GO 1000000

?

?問題重現

首先看一個非常有意思的問題,
在同一張表上,
先這么建一個索引:CREATE INDEX IDX_COL2_COL3 ON TestStatistics(COL2,COL3)
執行一個查詢,預估為4127.86
然后DROP掉上面的索引,繼續創建一個索引:CREATE INDEX IDX_COL3_COL2 ON TestStatistics(COL3,COL2)
注意COL2和COL3的順序不一致
繼續執行上面的查詢(查詢條件不變,數據不變,僅僅是索引列順序發生了變化),這一次預估為2414.91

?

查詢條件一樣,數據也一樣,為什么改變復合索引列順序會影響到執行計劃對數據行的預估呢?

?

?

?

?

首先來看第一個索引時候的預估算法:

  這個查詢他預估為4127.86行,如下圖

?

  說起來預估,就離不開統計信息,首先來看IDX_COL2_COL3這個索引的統計信息,
  我們知道,對于復合索引,統計信息中只有前導列的統計數據,也就是說IDX_COL3_COL2這個索引只有COL2這個列的統計信息,如下截圖
  對于COL2=2的統計信息,統計為100336行,我們記住這個數字

?

?

  統計信息的另外一個特點就是在會在查詢列(非索引列)上自動創建統計信息,如下截圖
  查詢執行過程中,自動創建了一個名字為:_WA_Sys_00000003_24E8431A的統計信息
  這個統計信息就是對COL3列的統計,可以發現在大于等于2012-10-20之后的統計行數


  在SQL Server 2012中,對數據行的預估計算方式是各個字段的選擇性的乘積,
  假如Pn代表不同字段的密度,那么預估行數的計算方法就是: 預估行數=p0*p1*p2*p3……*RowCount
  可以利用這個算法,計算目前數據下,預估出來的結果:4217.86,跟執行計劃預估是一致的,非常完美!

?

?

?

?   當刪除了IDX_COL2_COL3重建建立順序為COL3+COL2的索引的時候,預估如下

   與上面同樣的查詢條件,預估為2414.91行

?

?  

  依據上面的分析步驟,首先來分析索引列上的統計信息,如下截圖為大于等于2016-10-20之后的預估行數

?

?

同理,本次查詢也會自動建立COL2列上的統計信息(IDX_COL2_COL3索引被刪除),觀察這個統計信息對COL2=2的預估為83711.36行

   

   同樣我們利用上述公式,來計算預估的行數:2414.9035行,也非常完美地吻合和執行計劃預估的結果

   

?

  至此,應該很清楚一開始的問題了,就是為什么復合索引列順序不一致,在查詢的時候導致預估也不一致的原因。
  最根本的原因有就是:
  符合索引上只有前導列的統計信息,查詢引擎會根據需要自動創建非前導列的統計信息,
  但是,非常關鍵一點,如果細心的話,你會發現查詢引擎自動創建的統計信息的取樣行數都不是100%取樣的,這一點非常關鍵
  正是因為非前導列取樣有一定的誤差,導致在預估算法的時候,也即 預估行數=p0*p1*p2*p3……*RowCount的時候,密度值是不一樣的
  也即在創建IDX_COL2_COL3的時候,統計出來的COL2密度為P1_1,COL3密度為P2_1
  創建IDX_COL3_COL2的時候,統計出來的COL2密度為P1_2,COL3密度為P2_2,因為P1_1<>P1_2,P2_1<>P2_2
  因此,計算出的結果就是P1_1*P2_1<>P2_1*P2_2,原理很簡單,希望看官能明白。

  

?

  照這么計算,對于兩個順序不同的統計信息,如果P1_1=P2_1并且P2_1=P2_2,那么乘積就是一樣的,預估行數也就是一樣的,那么是不是呢?

  


  對于不同順序的兩個索引,先看COL2,COL3順序的索引
  在查詢一次之后(建立了統計信息),執行一個百分之百取樣(WITH FULLSCAN)的統計信息更新
  重新來看其預估行數,這一次預估為:2894.49

  

?

?

?  刪除COL2,COL3順序的索引,建立COL3,COL2為順序的索引
  在查詢一次之后(建立了統計信息),執行一個百分之百取樣(WITH FULLSCAN)的統計信息更新
  重新來看其預估行數,這一次預估為:同樣為2894.49,是吻合上述算法

?

?

?

?總結:

  文本簡單演示了執行計劃利用統計信息預估的算法和原理,以及在計算預估行數時候可能受到的干擾因素,
  這就要求我們在建立索引的時候,不僅僅是說我建一個復合索引就完事了,也要注意其索引列的順序對執行計劃預估的影響,
  更重要的是,要注意查詢引擎自動生成的統計信息對預估的影響程度。

  拋開統計信息談索引的,都是耍流氓。拋開統計信息取樣百分比談統計信息的,也是耍流氓。

  

  引申出來另外一個問題:維護統計信息的時候,能只更新索引列的統計信息,忽略非索引列的統計信息嗎?

?

本人技術能力還很菜,寫的不對的地方還請各位看官指出,謝謝。

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/542313.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/542313.shtml
英文地址,請注明出處:http://en.pswp.cn/news/542313.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

計算機三四級網絡技術,全國計算機等級考試四級網絡技術論述題真題3

1.(2003年)網絡安全策略設計的重要內容之一是&#xff1a;確定當網絡安全受到威脅時應采取的應急措施。當我們發現網絡受到非法侵入與攻擊時&#xff0c;所能采取的行動方案基本上有兩種&#xff1a;保護方式與跟蹤方式。請根據你對網絡安全方面知識的了解&#xff0c;討論以下…

哈密頓路徑_檢查圖形是否為哈密頓量(哈密頓路徑)

哈密頓路徑Problem Statement: 問題陳述&#xff1a; Given a graph G. you have to find out that that graph is Hamiltonian or not. 給定圖G。 您必須找出該圖是否為哈密頓量 。 Example: 例&#xff1a; Input: 輸入&#xff1a; Output: 1 輸出1 Because here is a …

京東自動下單軟件_黃牛軟件自動下單秒殺商品 警方用科技手段打擊

法制日報全媒體記者 張維定了10個鬧鐘,也搶不到一瓶茅臺&#xff1b;等了很久的iPhone新手機,打開網頁就秒沒……或許并不是因為你的手速、網速慢,而是黃牛黨在用軟件和你搶商品。近日,在“凈網2019”專項行動中,阿里安全協助江蘇省南通市公安局成功打掉了一個制作銷售黃牛軟件…

Mysql基礎之DML語句

增 1 給表的所有字段插入數據 INSERT INTO 表名 VALUES(值1&#xff0c;值2&#xff0c;值3&#xff0c;...&#xff0c;值n)&#xff1b; 2 給表的指定字段插入數據 INSERT INTO 表名(屬性1&#xff0c;屬性2&#xff0c;...&#xff0c;屬性n) VALUES(值1&#xff0c;值2&a…

河南招教考試計算機專業知識,河南教師招聘考試《計算機網絡技術基礎》知識點歸納七...

河南教師招聘考試《計算機網絡技術基礎》知識點歸納七1.ADSL是非對稱數字用戶線路&#xff0c;其下行速率為1.5&#xff5e;8 Mb/s&#xff0c;而上行速率則為16&#xff5e;640 kb/s。在一對銅雙絞線上的傳送距離可達5km左右&#xff0c;可同時上網打電話&#xff0c;互不影響…

Python程序檢查字符串是否是回文

What is palindrome string? 什么是回文字符串&#xff1f; A string is a palindrome if the string read from left to right is equal to the string read from right to left i.e. if the actual string is equal to the reversed string. 如果從左至右讀取的字符串等于…

content屬性的4種用途

content屬性瀏覽器支持情況&#xff0c;兼容到IE8瀏覽器&#xff0c;IE7及以下不支持用途一、配合:before及:after偽元素插入文本<div><p>偽元素</p> </div>p:before{content:CSS3;color:#4bb;font-weight:bold;margin-right:20px;background:#f0f0f0;…

內蒙古師范大學計算機科學技術學院,內蒙古師范大學計算機科學技術碩士生導師——李成城...

李成城&#xff0c;教授&#xff0c;碩導&#xff0c;1971年7月出生于內蒙古呼倫貝爾盟。2002年9月-2005年7月在北京郵電大學信息工程學院學習&#xff0c;獲得工學博士學位&#xff0c;主要研究領域是&#xff1a;自然語言理解、機器學習、圖像識別。1993年在內蒙古師范大學計…

超清世界地圖可放大_3D高清世界地圖

查看世界地圖的工具有哪些可以提供呢&#xff1f;3D世界地圖官方版是簡單好用的世界地圖工具&#xff0c;可以看到地球的大概模樣&#xff0c;選擇不一樣的海洋能看到不一樣的事物&#xff0c;這也是一款3d世界地圖高清地圖&#xff0c;需要用地圖軟件的可以下載。3D世界地圖官…

Java ObjectInputStream readUnshared()方法與示例

ObjectInputStream類readUnshared()方法 (ObjectInputStream Class readUnshared() method) readUnshared() method is available in java.io package. readUnshared()方法在java.io包中可用。 readUnshared() method is used to read "non-shared" or "unshare…

許多計算機英語,計算機英語翻譯

1數據是未經組織的事實的集合,數據可以包括單詞,數字,圖像和聲音.2計算機由許多硬件部件構成,這些硬件與軟件一起工作,以便執行計算,組織數據及與其他計算機通信的任務,3硬件部件包括輸入設備,輸出設備,系統單元 ,存儲設備和通信設備.4輸入設備讓用戶向計算機存儲器輸入數據和命…

工欲善其事必先利其器(一)

2019獨角獸企業重金招聘Python工程師標準>>> 寫在前面的話&#xff1a;紙上得來終學淺&#xff0c;絕知此事要躬行。還是自己敲一遍記得牢。 下載和安裝 Emmet為大部分流行的編輯器都提供了安裝插件&#xff0c;下面是它們的下載鏈接&#xff1a; Sublime Text Ecli…

windows 2008r2文件服務器部分用戶訪問不了_蘋果設備如何訪問 Windows 文件共享?...

前幾天寫了一篇關于 Mac 文件共享的。今天繼續聊聊 Mac、iPad 和 iPhone 如何訪問 Windows 的文件共享。Windows 開啟文件共享Windows 搜索并打開「高級共享設置」。在「專用」勾選「啟用網絡發現」和「啟用文件和打印機共享」。然后選擇一個 Windows 上想要共享的位置&#xf…

Java文件類boolean isDirectory()方法(帶示例)

文件類boolean isDirectory() (File Class boolean isDirectory()) This method is available in package java.io.File.isDirectory(). 軟件包java.io.File.isDirectory()中提供了此方法。 This method is used to check whether the file is specified by filepath is a dire…

微信小程序簡單入門1

參考文檔&#xff1a;https://mp.weixin.qq.com/debug/wxadoc/dev/index.html1 創建項目開發者工具安裝完成后&#xff0c;打開并使用微信掃碼登錄。選擇創建“項目”&#xff0c;填入上文獲取到的 AppID &#xff0c;&#xff08;無appid直接選擇&#xff09;設置一個本地項目…

leetcode數組匯總_LeetCode刷題實戰118:楊輝三角

算法的重要性&#xff0c;我就不多說了吧&#xff0c;想去大廠&#xff0c;就必須要經過基礎知識和業務邏輯面試算法面試。所以&#xff0c;為了提高大家的算法能力&#xff0c;這個公眾號后續每天帶大家做一道算法題&#xff0c;題目就從LeetCode上面選 &#xff01;今天和大家…

位運算使奇數+1 偶數-1_C ++程序打印從1到N的所有偶數和奇數

位運算使奇數1 偶數-1Problem: Take input from the user (N) and print all EVEN and ODD numbers between 1 to N. 問題&#xff1a;從用戶那里輸入(N)&#xff0c;并打印1至N之間的所有偶數和奇數編號。 Solution: 解&#xff1a; Input an integer number (N). 輸入一個整…

javascript 模塊化機制

1. 概述 js發展初期暴露了其缺陷&#xff1a;缺乏模塊&#xff0c;后來提出了commonJS規范來規范其模塊的規范。作為JavaScript新手&#xff0c;發現對于其JavaScript的模塊機制&#xff0c;不是很理解。我查閱了一些資料整理了JavaScript CommonJS的原理和機制。 2. JavaScrip…

c語言 宏定義 去除宏定義_如何檢查是否在C中定義了宏?

c語言 宏定義 去除宏定義To check whether a Macro is defined or not in C language – we use #ifdef preprocessor directive, it is used to check Macros only. 要檢查是否用C語言定義了宏 -我們使用#ifdef預處理程序指令&#xff0c;它僅用于檢查宏。 Syntax: 句法&…

多線程下不能用truncate嗎_那么多的化妝品,懷孕后都不能用了嗎?

前幾天圓夢參加了青島的美博會&#xff0c;里面的化妝品真多啊&#xff0c;無論是護膚、美白、彩妝比比皆是&#xff0c;看的人眼&#xff08;liu&#xff09;花&#xff08;lian&#xff09;繚&#xff08;wang&#xff09;亂&#xff08;fan&#xff09;。雖說國務院宣布的新…