在使用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個連續的頁組成的,區是最小的分配單...