SQL Server 查詢性能優化——堆表、碎片與索引(二)


 本文是對 SQL Server 查詢性能優化——堆表、碎片與索引(一)的一些總結。

 第一:先對 SQL Server 查詢性能優化——堆表、碎片與索引(一)中的例一的SET STATISTICS IO之后出現的關鍵信息如下

表 'T_EPZ_INOUT_ENTRY_DETAIL'。掃描計數 1,邏輯讀 4825 次,物理讀 次,預讀 19672 次。

這句解釋一下。(有些內容來自網絡,有些內部是自己的理解。)

 

SQL SERVER 數據庫引擎當遇到一個查詢語句時,SQL SERVER數據庫引擎會分別生成執行計划(占用CPU和內存資源),同時存儲引擎讀取 IAM 以生成必須要讀取的磁盤地址排序列表。這使 SQL Server 得以將其 I/O 優化為大型有序讀取,根據它們在磁盤上的位置按順序完成。磁盤中取得需要取的數據(占用I/O資源,這就是預讀),注 意,兩個步驟是並行的,SQL SERVER通過這種方式可以讓計算和 I/O 重疊進行,從而充分利用 CPU 和磁盤,從而提高性能。

 

掃描計數:查詢數據時對涉及到的表被 訪問次數或涉及到的索引的掃描次數。在我們的例子中,不管是表掃描(例一與例二)還是索引掃描(例三)其中的表或索引都只被訪問了1次,由於查詢中不包括連接命令,這一信息並不是十分有用,但如果查詢中包含有一個或多個連接,則這一信息是十分有用的。
  一個循環外部的表的掃描計數值為1,但對於一個循環內的表而言,其值為循環的次數。可以想象得到,對於一個循環內的表而言,其 掃描計數值越小,它所使用的資源越少,查詢的性能也就越高。因此在調節一個帶連接的查詢的性能時,需要關注掃描計數的值,在進行調節 時,注意觀察它是增加還是減少了。

邏輯讀: 這是SET STATISTICS IO或SET STATISTICS TIME命令提供的最有用的數據。我們知道,SQL Server在對任何數據進行操作前,必須首先從磁盤中讀取數據所在的數據頁或索引頁,並把數據頁或索引頁存到數據緩沖區高速緩存中。
  那么邏輯讀的意義是什么呢?邏輯讀是指SQL Server為得到查詢中的結果而必須從數據緩沖區高速緩存讀取的頁數。在執行查詢時,SQL Server不會讀取比實際需求多或少的數據, 因此,當在相同的數據集上執行同一個查詢,得到的邏輯讀的數字總是相同的。
  為什么說在調節查詢性能中知道SQL Server執行查詢時的邏輯讀值是很重要的呢?因為在每次執行同一查詢時,這個數值是不會變化的。因此,在進行查詢性能的調節時,這是一個可以用來衡量你的調節措施是否成功的一個很好的標准。
  在對查詢的性能進行調節時,如果邏輯讀值下降,就表明查詢使用的服務器資源減少,查詢的性能有所提高。如果邏輯讀值增加,則表示調節措施降低了查詢的性能。在其他條件不變的情況下,一個查詢使用的邏輯讀越少,其效率就越高,查詢的速度就越快。


物理讀:在這里我要說的的東西可能初聽起來有點自相矛盾,但只要反復思考,就會明白其中的真正含意。
  物理讀指的是,在執行真正的查詢操作前,SQL Server必須從磁盤上向數據緩沖區高速緩存中讀取它所需要的數據。在SQL Server開始執行查詢前,它要作的第一件事就是檢查它所需要的數據是否在數據緩沖區高速緩存中,如果在,就從中讀取,如果不在,SQL Server必須首先將它需要的數據從磁盤上讀到數據緩沖區高速緩存中。
  我們可以想象得到,SQL Server在執行物理讀時比執行邏輯讀需要更多的服務器資源。因此,在理想情況下,我們應當盡量避免物理讀操作。
  下面的這一部分聽起來讓人容易感到糊塗了。在對查詢的性能進行調節時,可以忽略物理讀而只專注於邏輯讀。你一定會納悶兒,剛才不是還說物理讀比邏輯讀需要更多的服務器資源嗎?
  情況確實是這樣,SQL Server在執行查詢時所需要的物理讀次數不可能通過性能調節而減少的。減少物理讀的次數是DBA的一項重要工作,但它涉及到整個服務器性能的調節,而不僅僅是查詢性能的調節。在進行查詢性能調節時,我們不能控制數據緩沖區高速緩存的大小或服務器的忙碌程度以及完成查詢所需要的數據是在數據緩沖區中還是在磁盤上,唯一我們能夠控制的數據是得到查詢結果所需要執行的邏輯讀的次數。
  因此,在查詢性能的調節中,我們可以心安理得地不理會SET STATISTICS IO命令提供的物理讀的值。(減少物理讀次數、加快SQL Server運行速度的一種方式是確保服務器的物理內存足夠多。)


預讀:與 物理讀一樣,這個值在查詢性能調節中也沒有什么用處。預讀表示SQL Server在執行預讀機制時從磁盤上讀取的數據頁或索引頁。為了優化其性能,SQL Server數據引擎首先預測執行查詢執行計划所需的數據和索引頁,然后在查詢實際使用這些頁之前將它們讀入緩沖區高速緩存。根據SQL Server對數據 需求預測的准確程度,預讀的數據頁可能有用,也可能沒用。

備注:一個緩沖區就是一個 8KB 大小的內存頁

 

以上文字大部分來源自網絡,本人對其中部分不認同處,或有自己的理解處,做了少量修改。

 


 

 

第二:關於碎片對於性能影響的結論:

SQL Server 中數據存儲的基本單位是頁,一頁包含8KB數據。磁盤 I/O 操作在頁級執行。也就是說,SQL Server 讀取或寫入的基本單位是數據頁。連續的8個頁面組成一個區(extent)。數據的insertupdate操作可以引起頁面分割產生碎片。如果分割后的兩個頁面在同一個區內,這種碎片稱為內部碎片,如果分割后的兩個頁面處於不同的區內,這種碎片稱為外部碎片。

一、內部碎片和外部碎片對數據檢索性能都有負面影響。

1. 內部碎片的產生使數據稀疏的分布在大量的頁面中,這增加了讀取頁面到內存中所需的磁盤I/O操作,增加了從內存中檢索數據的邏輯讀取數量。

2. 外部碎片導致磁盤上的索引頁面不連續,新的葉子頁面和原始葉子頁面離得很遠,物理順序與邏輯順序不同。為了更好的性能,首選順序I/O,因為這能在一個磁盤I/O讀取整個區(8個8KB頁面)。非連續的頁面需要非順序或者隨機I/O操作來從磁盤讀取數據,一個隨機I/O只能讀取一個頁面(8KB)。

 

二、在堆表中,當刪除數據鏈中間的記錄行時,會出現空頁,隨着空頁的累積,區的利用率也會下降,從而出現內部碎片與外部碎片。帶索引的表也有可能出現外部碎片,如在現有的聚集索引中插入一行,這行正好導致現有的頁空間無法滿足容納新的行,從而導致了分頁,如果分頁后的兩個頁面正好分布在兩個區,就是外部碎片。當有外部碎片存在,會出現以下問題:對表進行處理時,常常出現死鎖;利用較大的I/O操作或增加I/O緩沖區的大小也無法改變較慢的I/O速度;行操作的爭用。

 

三、帶有索引的表會由於插人記錄而導致分頁,但當刪除記錄后,頁會獲得釋放.從而形成跨幾個區的數據.而要訪問該數據就必須遍歷幾個區,這將導致增加I/O操作,查詢記錄的時間大大延長,開始時數據庫的性能雖然較高,但使用一段時間后就會發生性能下降等問題。實際上,數據在存儲空間上排列得越緊密有序,SQL Server訪問的速度就越抉,消除碎片有助於提高系統的性能和更有效地利用數據存儲空間。(如例二,例二的訪問速度就比例一要快)。

 

四、對於掃描部分或全部表的查詢,這些表碎片會導致額外的頁讀取,這將防礙數據的並行掃描。


免責聲明!

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



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