本文涉及的內容均不是原創,是記錄本身在學習IO、執行計劃的過程當中學習其餘大牛的博客和心得並記錄下來,之因此想寫下來是爲了記錄本身在追溯的過程遇到的幾個問題,並把這些問題弄清楚。 本章最後已貼出原文地址。html
要理解邏輯讀、物理讀、預讀這三個概念,先要搞懂SQL Server的數據存儲方式。數據庫
SQL Server數據庫包括數據文件和日誌文件,一個數據庫能夠有一個或多少數據文件、日誌文件。全部的數據存儲在數據文件中,數據文件能夠劃分爲再小的單元,咱們稱爲「頁」。每頁大小8k。8個頁面構成一個區。SQL Server對於頁的讀取是最原子性,要麼讀完一頁,要麼徹底不讀。頁之間的數據組織結構爲B樹。 因此SQL Server對於邏輯讀、物理讀、預讀的單位都是頁。緩存
2.1 初識三讀性能
先來看個例子。示例數據庫AdventureWorks。查詢Sales.SalesOrderDetail學習
從截圖中能夠看出,這裏讀取多少次也就是讀取了【多少頁】數據。這個也是我一開始沒搞懂的地方。優化
預讀:在查詢計劃生成的過程當中,用估計的信息去硬盤讀取數據到緩存中,預讀1242頁,也就是從硬盤中讀取了1242頁放到了緩存中。spa
物理讀:查詢計劃生成好之後,若是緩存缺乏所須要的數據,再從硬盤裏讀取缺乏的數據到緩存裏。.net
邏輯讀:從緩存中讀取數據。邏輯讀1240次,也就是從緩存中讀取1240頁數據。日誌
2.2 邏輯讀、物理讀、預讀的關係htm
再次運行上面的語句得出如下結果
從圖中能夠看出,此次沒有屋裏讀取和預讀次數,只有邏輯讀取次數,根據前面的概念咱們能夠分析出:第二次查詢能夠直接從緩存中讀取所須要的數據。 按照咱們的理論,貌似邏輯讀取次數=物理讀取次數+預讀次數。但你會發現前面咱們1240並不等於1242+3.這又是爲何呢?
一、首先要說明,邏輯讀取次數並不絕對等於物理讀取次數和預讀次數之和。第二次查詢物理讀取次數和預讀次數都是0。預讀是按照估計的信息去讀取信息,所以讀取的頁數並不必定準確,可能多於也可能少於實際的頁數。
二、若是預讀的頁數包括了所有數據,那麼就不會有物理讀取次數。
三、有時候出現邏輯讀取次數大於物理讀取次數加上預讀次數,這是由於在預讀以前緩存中已經存在部分須要的數據。
當SQL Server執行一個查詢時,SQL Server會開始第一步,生成執行計劃。同時用估計的數據去硬盤讀取數據(預讀)。這兩個第一步是並行的,SQL Server經過這種方式來提升查詢性能。執行計劃生成好之後去緩存讀取數據。當發現緩存缺乏所須要的數據後讓緩存再次去讀硬盤(物理讀)。而後從緩存中讀取全部數據(邏輯讀)。
估計的頁數也能夠從這個DMV中查詢。若是第二次緩存後可以使用DBCC DROPCLEANBUFFERS清理緩存(生產慎用)。
SELECT page_count FROM sys.dm_db_index_physical_stats (DB_ID('AdventureWorks2008R2'),OBJECT_ID('Sales.SalesOrderDetail'),NULL,NULL,'sampled')
理解邏輯讀、物理讀、預讀這三個概念主要是理解語句的查詢過程以及那個步驟是去緩存數據、那個步驟又是去硬盤讀取數據、那個步驟又是根據估計的信息去讀取數據。從應用的角度來講這三個數量並非絕對的數量加和關係,關鍵仍是要看理論語句的查詢過程。在對語句進行優化時重點仍是邏輯讀的次數,經過優化語句來檢查邏輯讀的次數來減小IO開銷。
http://www.canway.net/Original/shujuku/012CE2016.html
http://www.cnblogs.com/CareySon/archive/2011/12/23/2299127.html
http://www.cnblogs.com/kissdodog/archive/2013/06/25/3155016.html