SQL Server數據存儲的形式
- 預讀:用估計信息,去硬盤讀取數據到緩存。預讀100次,也就是估計將要從硬盤中讀取了100頁數據到緩存。
- 物理讀:查詢計划生成好以后,如果緩存缺少所需要的數據,讓緩存再次去讀硬盤。物理讀10頁,從硬盤中讀取10頁數據到緩存。
- 邏輯讀:從緩存中取出所有數據。邏輯讀100次,也就是從緩存里取到100頁數據。
SQL Server存儲的最小單位是頁,每一頁大小為8K,SQL Server對於頁的讀取是原子性的,要么讀完一頁,要么完全不讀。即使是僅僅要獲得一條數據,也要讀完一頁。而頁之間的數據組織結構為B樹結構。所以SQL Server對於邏輯讀、預讀、物理讀的單位是頁。
先來看一個查詢:
DBCC DROPCLEANBUFFERS --清空緩存 SET STATISTICS IO ON --開啟IO統計 SELECT * FROM Person --查詢語句
顯示消息如下:
(147517 行受影響) 表 'Person'。掃描計數 1,邏輯讀取 2237 次,物理讀取 6 次,預讀 2226 次,lob 邏輯讀取 0 次,lob 物理讀取 0 次,lob 預讀 0 次。 (1 行受影響)
上表的大小是17.406M。
每一頁存儲的數據是:8K=8192字節-96字節(頁頭)-36字節(行偏移)= 8060字節。
17.406*1024*1024 / 8060 ≈ 2 264
另外表中還有一些非數據占用的空間,因此上式的結果約等於邏輯讀次數。
基本上,邏輯讀、物理讀、預讀都等於是掃描了多少個頁。
從執行順序上理解各種讀
SQL Server的查詢從理解各種讀的步驟來看,可以理解為以下圖:
(圖是CareySon大哥的)
通過上圖來講解各種讀:
當SQL Server執行一個查詢語句時,SQL Serer會開始第一步,生成查詢計划,同時用估計的數據去磁盤讀取數據(預讀),這兩個第一步是並行的。SQL Server通過這種方式來提高查詢性能。
查詢計划生成好了以后去緩存讀取數據,當發現緩存缺少所需要的數據后讓緩存再次去讀硬盤(物理讀),然后從緩存中取出所有數據(邏輯讀)。
估計的頁數可以通過DMV看到
SELECT page_count FROM sys.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 次。 (1 行受影響)
為什么這次全部都是邏輯讀呢。因為剛才讀過一次,數據全部都已經在緩存當中了,只需要從緩存中讀就可以了,不需要再讀取硬盤。
本文學習自:http://www.cnblogs.com/CareySon/archive/2011/12/23/2299127.html