物理讀,邏輯讀,預讀

2022-01-12 21:58:48 字數 2310 閱讀 8398

在使用set statistics io on語句統計i/o時候,我們會看到類似下面的結果:

掃瞄計數 1,邏輯讀取 2 次,物理讀取 0 次,預讀 0 次,lob 邏輯讀取 0 次,lob 物理讀取 0 次,lob 預讀 0 次。

那麼它們代表什麼呢?

預讀:用於估計資訊,去硬碟讀取資料到快取。

物理讀:查詢計畫生成好以後,如果快取缺少所需要的資料,讓快取再次去讀硬碟。如果記憶體裡沒有快取資料或執行計畫(sql語句改變執行計畫不能重用,需要重新計算執行計畫),那麼sqlserver就要去硬碟讀取這些資料,這時候就是物理讀,硬碟速度跟記憶體速度不在乙個數量級別,所以物理讀是比較慢的。

邏輯讀:sqlserver去記憶體裡面的緩訪問資料或執行計畫(執行計畫可以重用),所以邏輯讀是比較快的。

sql server儲存的最小單位是頁,每一頁大小為8k,sql server對於頁的讀取是原子性的,要麼讀完一頁,要麼完全不讀。即使是僅僅要獲得一條資料,也要讀完一頁。而頁之間的資料組織結構為b樹結構。所以sql server對於邏輯讀、預讀、物理讀的單位是頁。

先來看乙個查詢:

dbccdropcleanbuffers    --清空快取

setstatisticsio on--開啟io統計

select*fromperson --查詢語句

顯示訊息如下:

(147517 行受影響)

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

上表的大小是17.406m。

每一頁儲存的資料是:8k=8192位元組-96位元組(頁頭)-36位元組(行偏移)= 8060位元組。

17.406*1024*1024 / 8060 ≈ 2 264

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

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

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

通過上圖來講解各種讀:

當sql server執行乙個查詢語句時,sql serer會開始第一步,生成查詢計畫,同時用估計的資料去磁碟讀取資料(預讀),這兩個第一步是並行的。sql server通過這種方式來提高查詢效能。

查詢計畫生成好了以後去快取讀取資料,當發現快取缺少所需要的資料後讓快取再次去讀硬碟(物理讀)然後從快取中取出所有資料(邏輯讀)

估計的頁數可以通過dmv看到

select

page_count

fromsys.dm_db_index_physical_stats

(db_id('testdatacenter'),object_id('person'),null,null,'sampled')

顯示結果如下:

sql server就是根據這個東西進行預讀。

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

select * from person    --查詢語句

看到訊息如下:

(147517行受影響)

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

為什麼這次全部都是邏輯讀呢。因為剛才讀過一次,資料全部都已經在快取當中了,只需要從快取中讀就可以了,不需要再讀取硬碟。

SQL Server邏輯讀 預讀和物理讀

預讀 用估計資訊,去硬碟讀取資料到快取。預讀100次,也就是估計將要從硬碟中讀取了100頁資料到快取。物理讀 查詢計畫生成好以後,如果快取缺少所需要的資料,讓快取再次去讀硬碟。物理讀10頁,從硬碟中讀取10頁資料到快取。邏輯讀 從快取中取出所有資料。邏輯讀100次,也就是從快取裡取到100頁資料。s...

SQLSERVER預讀邏輯讀物理讀

預讀 用估計資訊,去硬碟讀取資料到快取。預讀100次,也就是估計將要從硬碟中讀取了100頁資料到快取。物理讀 查詢計畫生成好以後,如果快取缺少所需要的資料,讓快取再次去讀硬碟。物理讀10頁,從硬碟中讀取10頁資料到快取。邏輯讀 從快取中取出所有資料。邏輯讀100次,也就是從快取裡取到100頁資料。l...

SQL Server邏輯讀 預讀 物理讀

sql server邏輯讀 預讀 物理讀 sql server 儲存資料的方式 1.頁是最小的操作單元,也就是說從磁碟讀取資料庫的時候最少讀取一頁,每一頁的大小是8kb,sql server對於頁的讀取是原子性,要麼讀完一頁,要麼完全不讀,不會有中間狀態 2.區是8個連續的頁組成的,區是最小的分配單...