程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> 其他數據庫知識 >> MSSQL >> SQLSERVER搜集語句運轉的統計信息並停止剖析

SQLSERVER搜集語句運轉的統計信息並停止剖析

編輯:MSSQL

SQLSERVER搜集語句運轉的統計信息並停止剖析。本站提示廣大學習愛好者:(SQLSERVER搜集語句運轉的統計信息並停止剖析)文章只能為提供參考,不一定能成為您想要的結果。以下是SQLSERVER搜集語句運轉的統計信息並停止剖析正文


關於語句的運轉,除履行籌劃自己,還有一些其他身分要斟酌,例如語句的編譯時光、履行時光、做了若干次磁盤讀等。

假如DBA可以或許把成績語句零丁測試運轉,可以在運轉前翻開上面這三個開關,搜集語句運轉的統計信息。
這些信息對剖析成績很有價值。

SET STATISTICS TIME ON
SET STATISTICS IO ON
SET STATISTICS PROFILE ON

SET STATISTICS TIME ON
--------------------------------------------------------------------------------
請先來看看SET STATISTICS TIME ON會前往甚麼信息。先運轉語句:

DBCC DROPCLEANBUFFERS
--消除buffer pool裡的一切緩存數據
DBCC freeproccache
GO
--消除buffer pool裡的一切緩存的履行籌劃
SET STATISTICS TIME ON
GO
USE [AdventureWorks]
GO
SELECT DISTINCT([ProductID]),[UnitPrice] FROM [dbo].[SalesOrderDetail_test]
WHERE [ProductID]=777
GO
SET STATISTICS TIME OFF
GO

除成果集以外,SQLSERVER還會前往上面這兩段信息

SQL Server 剖析和編譯時光:
CPU 時光 = 15 毫秒,占用時光 = 104 毫秒。
SQL Server 剖析和編譯時光:
CPU 時光 = 0 毫秒,占用時光 = 0 毫秒。
(4 行受影響)
SQL Server 履行時光:
CPU 時光 = 171 毫秒,占用時光 = 1903 毫秒。
SQL Server 剖析和編譯時光:
CPU 時光 = 0 毫秒,占用時光 = 0 毫秒。

年夜家曉得SQLSERVER履行語句是分以下階段:剖析-》編譯-》履行
依據表格的統計信息剖析出比擬適合的履行籌劃,然後編譯語句,最初履行語句

上面說一下下面的輸入是甚麼意思:
--------------------------------------------------------------------------------
1、CPU時光 :這個值的寄義指的是在這一步,SQLSERVER所花的純CPU時光是若干。也就是說,語句花了若干CPU資本
2、占用時光 :此值指這一步一共用了若干時光。也就是說,這是語句運轉的時光長短,有些舉措會產生I/O操作,發生了I/O期待,或許是碰到壅塞、發生了壅塞期待。總之時光用失落了,然則沒有效CPU資本。所以占用時光比CPU時光長是很正常的 ,然則CPU時光是語句在一切CPU上的時光總和。假如語句應用了多顆CPU,而其他期待簡直沒有,那末CPU時光年夜於占用時光也是正常的
3、剖析和編譯時光:這一步,就是語句的編譯時光。因為語句運轉之前清空了一切履行籌劃,SQLSERVER必需要對他編譯。
這裡的編譯時光就不為0了。因為編譯重要是CPU的運算,所以普通CPU時光和占用時光是差不多的。假如這裡相差比擬年夜,就有需要看看SQLSERVER在體系資本上有無瓶頸了。
這裡他們是一個15毫秒,一個是104毫秒
4、SQLSERVER履行時光: 語句真正運轉的時光。因為語句是第一次運轉,SQLSERVER須要把數據從磁盤讀到內存裡,這裡語句的運轉產生了比擬長的I/O期待。所以這裡的CPU時光和占用時光差異就很年夜了,一個是171毫秒,而另外一個是1903毫秒

總的來說,這條語句花了104+1903+186=2193毫秒,個中CPU時光為15+171=186毫秒。語句的重要時光應當是都花在了I/O期待上

如今再做一遍語句,然則不消除任何緩存

SET STATISTICS TIME ON
GO
SELECT DISTINCT([ProductID]),[UnitPrice] FROM [dbo].[SalesOrderDetail_test]
WHERE [ProductID]=777
GO
SET STATISTICS TIME OFF
GO

此次比前次快許多。輸入時光統計信息是:

SQL Server 剖析和編譯時光:
CPU 時光 = 0 毫秒,占用時光 = 0 毫秒。
SQL Server 剖析和編譯時光:
CPU 時光 = 0 毫秒,占用時光 = 0 毫秒。
(4 行受影響)
SQL Server 履行時光:
CPU 時光 = 156 毫秒,占用時光 = 169 毫秒。
SQL Server 剖析和編譯時光:
CPU 時光 = 0 毫秒,占用時光 = 0 毫秒。

因為履行籌劃被重用,“SQL剖析和編譯時光” CPU時光是0,占用時光是0
因為數據曾經緩存在內存裡,不須要從磁盤上讀取,SQL履行時光 CPU時光是156,占用時光此次和CPU時光異常接近,是169。

這裡省下運轉時光1903-169=1734毫秒,從這裡可以再次看出,緩存對語句履行機能起著相當主要的感化
為了不影響其他測試,請運轉上面的語句封閉SET STATISTICS TIME ON

SET STATISTICS TIME OFF 
GO

SET STATISTICS IO ON
--------------------------------------------------------------------------------
這個開關可以或許輸入語句做的物理讀和邏輯讀的數量。對剖析語句的龐雜度有很主要的感化
照樣以適才誰人查詢作為例子

DBCC DROPCLEANBUFFERS
GO
SET STATISTICS IO ON
GO
SELECT DISTINCT([ProductID]),[UnitPrice] FROM [dbo].[SalesOrderDetail_test]
WHERE [ProductID]=777
GO

他的前往是: 
(4 行受影響)
表 'SalesOrderDetail_test'。掃描計數 5,邏輯讀取 15064 次,物理讀取 0 次,預讀 15064 次,lob 邏輯讀取 0 次,lob 物理讀取 0 次,lob 預讀 0 次。
各個輸入的寄義是:
--------------------------------------------------------------------------------
表:表的稱號。這裡的表就是SalesOrderDetail_test

掃描計數:履行的掃描次數。依照履行籌劃,表格被掃描了幾回。普通來說年夜表掃描的次數越多越欠好。獨一的破例是假如履行籌劃選擇了並發運轉, 由多個thread線程同時做一個表的讀取,每一個thread讀個中的一部門,然則這裡會顯示一切thread的數量。也就是有幾個thread在並發做, 就會有幾個掃描。這時候數量年夜一點沒成績的。

邏輯讀取:從數據緩存讀取的頁數。頁數越多,解釋查詢要拜訪的數據量就越年夜,內存消費量越年夜,查詢也就越昂貴。

可以檢討能否應當調劑索引,削減掃描的次數,減少掃描規模
物理讀取:從磁盤讀取的頁數
預讀:為停止查詢而預讀入緩存的頁數
物理讀取+預讀:就是SQLSERVER為了完成這句查詢而從磁盤上讀取的頁數。假如不為0,解釋數據沒有緩存在內存裡。運轉速度必定會遭到影響
LOB邏輯讀取:從數據緩存讀取的text、ntext、image、年夜值類型(varchar(max)、nvarchar(max)、varbinary(max))頁的數量
LOB物理讀取:從磁盤讀取的text、ntext、image、年夜值類型頁的數量
LOB預讀:為停止查詢而放入緩存的text、ntext、image、年夜值類型頁的數量
然後再來運轉一遍,不清空緩存

SET STATISTICS IO ON
GO
SELECT DISTINCT([ProductID]),[UnitPrice] FROM [dbo].[SalesOrderDetail_test]
WHERE [ProductID]=777
GO

成果集前往:

1 表 'SalesOrderDetail_test'。掃描計數 5,邏輯讀取 15064 次,物理讀取 0 次,預讀 0 次,lob 邏輯讀取 0 次,
2 lob 物理讀取 0 次,lob 預讀 0 次。

此次邏輯讀取不變,照樣15064頁。然則物理讀取和預讀都是0了。解釋數據曾經緩存在內存裡第二次運轉不須要再從磁盤上讀一遍,節儉了時光為了不影響其他測試,請運轉上面語句封閉SET STATISTICS IO ON

SET STATISTICS IO OFF
GO

SET STATISTICS PROFILE ON
--------------------------------------------------------------------------------
這是三個設置中前往最龐雜的一個,他前往語句的履行籌劃,和語句運轉在每步的現實前往行數統計。
經由過程這個成果,不只可以獲得履行籌劃,懂得語句履行進程,剖析語句調優偏向,也能夠斷定SQLSERVER能否
選擇了一個准確的履行籌劃。

SET STATISTICS PROFILE ON
GO
SELECT COUNT(b.[SalesOrderID])
FROM [dbo].[SalesOrderHeader_test] a
INNER JOIN [dbo].[SalesOrderDetail_test] b
ON a.[SalesOrderID]=b.[SalesOrderID]
WHERE a.[SalesOrderID]>43659 AND a.[SalesOrderID]<53660
GO

前往的成果集很長,上面說一下主要字段
--------------------------------------------------------------------------------

留意:這裡是從最上面開端向上看的,也就是說從最上面開端一向履行直到獲得成果集所以(行1)裡的rows字段顯示的值就是這個查詢前往的成果集。

並且有若干行注解SQLSERVER履行了若干個步調,這裡有6行,注解SQLSRVER履行了6個步調!!
Rows:履行籌劃的每步前往的現實行數
Executes:履行籌劃的每步被運轉了若干次
StmtText:履行籌劃的詳細內容。履行籌劃以一棵樹的情勢顯示。每行都是運轉的一步,都邑有成果集前往,也都邑有本身的cost
EstimateRows:SQLSERVER依據表格上的統計信息,預估的每步的前往行數。在剖析履行籌劃時,我們會常常將Rows和EstimateRows這兩列做比較,先確認SQLSERVER預估得能否准確,以斷定統計信息能否有更新
EstimateIO:SQLSERVER依據EstimateRows和統計信息裡記載的字段長度,預估的每步會發生的I/O cost
EstimateCPU:SQLSERVR依據EstimateRows和統計信息裡記載的字段長度,和要做的工作的龐雜度,預估每步會發生的CPU cost
TotalSubtreeCost:SQLSERVER依據EstimateIO和EstimateCPU經由過程某種盤算公式,盤算出每步履行籌劃子樹的cost (包含這一步本身的cost和他的一切基層步調的cost總和),上面引見的cost說的都是這個字段值
Warnings:SQLSERVER在運轉每步時碰到的正告,例如,某一步沒有統計信息支撐cost預估等。
Parallel:履行籌劃的這一步是否是應用了並行的履行籌劃

從下面成果可以看出履行籌劃分紅4步,個中第一步又分紅並列的兩個子步調
步調a1(第5行):從[SalesOrderHeader_test]內外找出一切a.[SalesOrderID]>43659 AND a.[SalesOrderID]<53660的值
由於表在這個字段上有一個集合索引,所以SQL可以直接應用這個索引的seek
SQL猜測前往10000筆記錄,現實也就前往了10000筆記錄.。這個猜測是精確的。這一步的cost是0.202(totalsubtreecost)
步調a2(第6行):從[SalesOrderDetail_test]內外找出一切 a.[SalesOrderID]>43659 AND a.[SalesOrderID]<53660的值
由於表在這個字段上有一個非集合索引,所以SQL可以直接應用這個索引的seek 這裡可以或許看出SQL聰慧的處所。固然查詢語句只界說了[SalesOrderHeader_test]表上有a.[SalesOrderID]>43659 AND a.[SalesOrderID]<53660過濾前提,然則依據語義剖析,SQL曉得這個前提在[SalesOrderDetail_test]上也為真。所以SQL選擇先把這個前提過濾然後再做join。如許可以或許年夜年夜下降join的cost
在這一步SQL預估前往50561筆記錄,現實前往50577條。cost是0.127,也不高
步調b(第4行):將a1和a2兩步獲得的成果集做一個join。由於SQL經由過程預估曉得這兩個成果集比擬年夜,所以他直接選擇了Hash Match的join辦法。
SQL預估這個join能前往50313行,現實前往50577行。由於SQL在兩張表的[SalesOrderID]上都有統計信息,所以這裡的預估異常精確
這一步的cost等於totalsubtreecost減去他的子步調,0.715-0.202-0.127=0.386。因為預估值異常精確,可以信任這裡的cost就是現實每步的cost
步調c(第3行):在join前往的成果集基本上算count(*)的值這一步比擬簡略,count(*)的成果老是1,所以猜測值是准確的。
其實這一步的cost是依據上一步(b)join前往的成果集年夜小預估出來的。我們曉得步調b的預估前往值異常精確,所以這一步的預估cost也不會有甚麼年夜成績
這棵子樹的cost是0.745,減去他的子節點cost,他本身的cost是0.745-0.715=0.03。是消費很小的一步
步調b(第2行):將步調c前往的值轉換為int類型,作為成果前往
這一步是上一步的持續,更加簡略。convert一個值的數據類型所要的cost簡直可以疏忽不計。所以這棵子樹的cost和他的子節點相等,都是0.745。
也就是說,他本身的cost是0
經由過程如許的辦法,用戶可以懂得到語句的履行籌劃、SQLSERVER預估的精確性、cost的散布
最初說一下:分歧SQLSERVER版本,分歧機械cost能夠會紛歧樣,例如SQL2005 ,SQL2008
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved