|
問: 我最近升級了一個應用程序,使其可以在 SQL Server 2005 上運行。我利用了允許行長度超出 8,060 個字節這項功能,以便用戶可以創建較長的數據字段而不會收到從 SQL Server 返回的錯誤。現在,將這個應用程序應用到實際環境之后,一些掃描查詢開始出現性能問題,在架構更改之前,這些查詢運行正常。我也檢查過各種索引的碎片,一切正常。那為什么查詢在 SQL Server 2005 上運行時速度比較慢呢?
答: 您所利用的“行溢出”功能,對于在特定情況下允許行長度大于 8,060 個字節效果很好,但卻不適合大多數長度過大的行,而且可能使查詢性能大打折扣,正如您所遇到的情況那樣。
發生這種情況的原因是,當某行的長度開始變得過大時,該行中的其中一個可變長度列會被“推出行”。這意味著該列會在數據或索引頁上從行中移到文本頁中。至于原來列中的值,會由指針取代,指向該列中的值在數據文件中的新位置。
這與用來存儲 XML、文本、圖像或 varchar(max) 等常規 LOB(大型對象)列的機制完全相同。請注意,如果表架構包含多個可變長度列,就無法保證在多個行的長度變得過大時推出的會是同一列。
這種機制可能會產生性能問題。如果查詢從一個表格行中檢索的可變長度列已被推出該行,可能突然之間需要額外的 I/O 來讀取內含行外位置的值的文本頁。如果有多個行的長度過大,從多個行中檢索相同的可變長度列的查詢,可能產生無法預料的性能問題,嚴重程度取決于被推出行的值的數量。
在您遇到的情況中,對包含可變長度列的選擇列表執行范圍掃描或表掃描的查詢,正是因行溢出及其影響而導致性能下降。這與索引是否執行過完全的碎片整理無關,當可變長度列被推出行時,因為必須使用隨機 I/O 讀取內含行外的值的文本頁,所以之前有效的掃描作業已基本中斷。
雖然行溢出在特定的情況下對于長度過大的行仍然很有用,但如果查詢的性能至關重要,則不應該在您的設計里面過度利用。
問: 我們剛在兩個故障轉移群集之間引入了數據庫鏡像,作為以低于存儲區域網絡 (SAN) 復制的成本獲得地理冗余的方法。因為數據中心位于同一個城市,所以我們能夠使用同步鏡像。問題在于當本地群集上發生故障轉移時,鏡像數據庫會故障轉移到遠程群集,而這并不是我們希望發生的情況。我們該如何避免出現這種情況?我們只希望在本地群集無法使用的時才進行故障轉移。
答: 為了提高可用性,鏡像會安裝一個見證服務器,以便在主體服務器無法使用時自動發生故障轉移。其理論基礎是:如果整個本地群集出現故障,數據庫鏡像將故障轉移到第二個群集,這樣應用程序就可以繼續執行了。
此問題出現在群集故障轉移期間。故障轉移所花的時間超過了數據庫鏡像的默認超時設置,而見證服務器和鏡像服務器(即第二個群集上活動的 SQL Server 實例)均認為它們看不到主體服務器,于是鏡像服務器便開始將鏡像故障轉移到第二個群集。
預防這種現象最簡單的方法是刪除見證服務器,以便數據庫鏡像在本地群集出現故障時不會自動進行故障轉移。當然,這種做法會降低可用性,因為這樣一來就需要人為啟動故障轉移。
第二種方法是更改數據庫鏡像的默認超時設置,也就是更改確定主體服務器不可用之前,它響應“ping”信息(每秒一次)失敗的次數。這種設置稱為“伙伴超時”(Parnter Timeout),默認值為 10。可使用下列代碼找到數據庫當前的超時值:
1. SELECT mirroring_connection_timeout
2. FROM master.sys.database_mirroring
3. WHERE database_id = DB_ID ('mydbname');
4. GO
it知識庫:SQL問題與解答:行溢出、差異備份及更多內容,轉載需保留來源!
鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯系我們修改或刪除,多謝。