對于語句的運(yùn)行,除了執(zhí)行計(jì)劃本身,還有一些其他因素要考慮,例如語句的編譯時間、執(zhí)行時間、做了多少次磁盤讀等。
如果DBA能夠把問題語句單獨(dú)測試運(yùn)行,可以在運(yùn)行前打開下面這三個開關(guān),收集語句運(yùn)行的統(tǒng)計(jì)信息。
這些信息對分析問題很有價(jià)值。
復(fù)制代碼 代碼如下:
SET STATISTICS TIME ON
SET STATISTICS IO ON
SET STATISTICS PROFILE ON
SET STATISTICS TIME ON
--------------------------------------------------------------------------------
請先來看看SET STATISTICS TIME ON會返回什么信息。先運(yùn)行語句:
復(fù)制代碼 代碼如下:
DBCC DROPCLEANBUFFERS
--清除buffer pool里的所有緩存數(shù)據(jù)
DBCC freeproccache
GO
--清除buffer pool里的所有緩存的執(zhí)行計(jì)劃
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
除了結(jié)果集之外,SQLSERVER還會返回下面這兩段信息
復(fù)制代碼 代碼如下:
SQL Server 分析和編譯時間:
CPU 時間 = 15 毫秒,占用時間 = 104 毫秒。
SQL Server 分析和編譯時間:
CPU 時間 = 0 毫秒,占用時間 = 0 毫秒。
(4 行受影響)
SQL Server 執(zhí)行時間:
CPU 時間 = 171 毫秒,占用時間 = 1903 毫秒。
SQL Server 分析和編譯時間:
CPU 時間 = 0 毫秒,占用時間 = 0 毫秒。
大家知道SQLSERVER執(zhí)行語句是分以下階段:分析-》編譯-》執(zhí)行
根據(jù)表格的統(tǒng)計(jì)信息分析出比較合適的執(zhí)行計(jì)劃,然后編譯語句,最后執(zhí)行語句
下面說一下上面的輸出是什么意思:
--------------------------------------------------------------------------------
1、CPU時間 :這個值的含義指的是在這一步,SQLSERVER所花的純CPU時間是多少。也就是說,語句花了多少CPU資源
2、占用時間 :此值指這一步一共用了多少時間。也就是說,這是語句運(yùn)行的時間長短,有些動作會發(fā)生I/O操作,產(chǎn)生了I/O等待,或者是遇到阻塞、產(chǎn)生了阻塞等待。總之時間用掉了,但是沒有用CPU資源。所以占用時間比CPU時間長是很正常的 ,但是CPU時間是語句在所有CPU上的時間總和。如果語句使用了多顆CPU,而其他等待幾乎沒有,那么CPU時間大于占用時間也是正常的
3、分析和編譯時間:這一步,就是語句的編譯時間。由于語句運(yùn)行之前清空了所有執(zhí)行計(jì)劃,SQLSERVER必須要對他編譯。
這里的編譯時間就不為0了。由于編譯主要是CPU的運(yùn)算,所以一般CPU時間和占用時間是差不多的。如果這里相差比較大,就有必要看看SQLSERVER在系統(tǒng)資源上有沒有瓶頸了。
這里他們是一個15毫秒,一個是104毫秒
4、SQLSERVER執(zhí)行時間: 語句真正運(yùn)行的時間。由于語句是第一次運(yùn)行,SQLSERVER需要把數(shù)據(jù)從磁盤讀到內(nèi)存里,這里語句的運(yùn)行發(fā)生了比較長的I/O等待。所以這里的CPU時間和占用時間差別就很大了,一個是171毫秒,而另一個是1903毫秒
總的來講,這條語句花了104+1903+186=2193毫秒,其中CPU時間為15+171=186毫秒。語句的主要時間應(yīng)該是都花在了I/O等待上
現(xiàn)在再做一遍語句,但是不清除任何緩存
復(fù)制代碼 代碼如下:
SET STATISTICS TIME ON
GO
SELECT DISTINCT([ProductID]),[UnitPrice] FROM [dbo].[SalesOrderDetail_test]
WHERE [ProductID]=777
GO
SET STATISTICS TIME OFF
GO
這次比上次快很多。輸出時間統(tǒng)計(jì)信息是:
復(fù)制代碼 代碼如下:
SQL Server 分析和編譯時間:
CPU 時間 = 0 毫秒,占用時間 = 0 毫秒。
SQL Server 分析和編譯時間:
CPU 時間 = 0 毫秒,占用時間 = 0 毫秒。
(4 行受影響)
SQL Server 執(zhí)行時間:
CPU 時間 = 156 毫秒,占用時間 = 169 毫秒。
SQL Server 分析和編譯時間:
CPU 時間 = 0 毫秒,占用時間 = 0 毫秒。
由于執(zhí)行計(jì)劃被重用,“SQL分析和編譯時間” CPU時間是0,占用時間是0
由于數(shù)據(jù)已經(jīng)緩存在內(nèi)存里,不需要從磁盤上讀取,SQL執(zhí)行時間 CPU時間是156,占用時間這次和CPU時間非常接近,是169。
這里省下運(yùn)行時間1903-169=1734毫秒,從這里可以再次看出,緩存對語句執(zhí)行性能起著至關(guān)重要的作用
為了不影響其他測試,請運(yùn)行下面的語句關(guān)閉SET STATISTICS TIME ON
復(fù)制代碼 代碼如下:
SET STATISTICS TIME OFF
GO
SET STATISTICS IO ON
--------------------------------------------------------------------------------
這個開關(guān)能夠輸出語句做的物理讀和邏輯讀的數(shù)目。對分析語句的復(fù)雜度有很重要的作用
還是以剛才那個查詢作為例子
復(fù)制代碼 代碼如下: