SQL SERVER中的邏輯讀取,物理讀取,以及預讀的理解


在SQLSERVER查詢分析器中,當我們用Set Statistics on 語句來統計SQL語句或者存儲過程I/O的時候,

SQLSERVER會顯示幾個概念去詞語:邏輯讀取,物理讀取,預讀。

如下:

(1 行受影響)
表 't2'。掃描計數 1,邏輯讀取 3282 次,物理讀取 44 次,預讀 3282 次,lob 邏輯讀取 0 次,lob 物理讀取 0 次,lob 預讀 0 次。

那么,這幾個詞語代表什么意思呢?我們怎么根據這些來了解SQL語句或者存儲過程的I/O過程呢?

預讀:用於估計信息,去硬盤讀取數據到緩存。

物理讀:查詢計划生成以后,如果發現緩存缺少所需要的數據,讓緩存再次去讀硬盤數據。如果內存里沒有緩存數據或者執行計划(如果SQL語句發生了改變,

那么執行計划將不能重用,需要重新生成新的執行計划),那么SQLSERVER就要去硬盤讀取這些數據,這個時候就是物理讀取,我們大家都知道,硬盤速度

與內存速度根本不在一個數量級上,所以物理讀是比較慢的。

邏輯讀:SQLSERVER去內存里的緩存取數據或者執行計划,所以邏輯讀是比較快的。

SQLSERVER存儲的最小單位是頁,每一頁大小為8K,即8*1024=8192字節,SQLSERVER對頁的讀取是原子性的,即要么讀完一頁,要么完全不讀。即使

僅僅要獲得一條數據,也要讀完該頁,而頁之間的數據組織結構為B樹結構。所以SQLSERVER對於邏輯讀,物理讀,預讀的單位是頁。

先來看一個查詢:

DBCC DROPCLEANBUFFERS  --清空緩存

SET STATISTICS IO ON     --開啟IO統計

SELECT * FROM SAMPLE   --查詢

顯示消息如下:

(147517 行受影響)

表'SAMPLE'。掃描計數 1,邏輯讀取2237次,物理讀取6次,預讀2226次,lob讀取0次

上表的大小事17.406M。

每一頁存儲的數據是8K=8192字節-96字節(頁頭)-36字節(行偏移)=8060字節。

17.406*1024*1024/8060約等於2264.

另外表中還有一些非數據占用的空間,因此上式的結果約等於邏輯讀次數。

基本上,邏輯讀,物理讀,預讀都等於是掃描了多少個頁。

SQLSERVER的查詢從理解各種讀的步驟來看,可以理解為下圖

通過上圖來解釋下各種讀的方式:

SQLSERVER執行一個查詢語句的時候,SQLSERVER會執行第一個步驟,即生成查詢計划,同時用估計的數據去磁盤讀取數據(預讀)

,這兩個都是第一步,是並行的。SQLSERVER通過這種方式來提高查詢性能。

當查詢計划生成好以后,開始去緩存讀取數據,當發現緩存缺少所需要的數據的時候,讓緩存再次去硬盤讀取數據(物理讀),然后從緩存

中取出所有數據(邏輯讀)。

估計的頁數可以通過DMV來看到

select pagecount from sys.dm_db_index_physical_stats

(DB_ID('TESTDATACENTER'),OBJECT_ID('SAMPLE'),null,null,'sampled')

顯示結果如下:

SQLSERVER就是根據這個數值進行預讀的。

如果我們此時再執行上面的查詢語句

select * from sample  --查詢

看到消息如下:

(147517 行受影響)

表'SAMPLE'。掃描計數1,邏輯讀取2237次,物理讀取0次,預讀0次,lob邏輯讀取0次。

讀者也許不明白了,為什么這次全部都是邏輯讀取呢?

答案是因為剛才執行過這樣一個查詢,執行計划與數據都在緩存當中,所以只需要從緩存中讀取就可以了,

不需要再讀取硬盤。

 

本文系自己消化並轉載

地址:http://www.studyofnet.com/news/94.html。

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM