共用方式為


SQL 問題與解答CPU 瓶頸、還原和移動資料庫...等等

由 Nancy Michell 編輯

問:我的 SQL Server™ CPU 使用量突然暴增,但是我沒有做任何變更,未增加新使用者、沒有硬體發生故障、未建立新資料表。因此到底發生了什麼事?

提示:在建立索引期間的存取

有的時候,當您想要對大型資料表建立索引時 (此舉可能要花費大量的時間),但是卻希望讓資料在此程序的期間仍可使用。您該如何同時達到這兩個目標呢?

叢集索引在建立、刪除或是重建時,SQL Server 都會在資料表上附加結構描述修改 (SCH-M) 鎖定,此舉可以防止所有使用者在此作業期間,存取基礎的資料。這就是當您對資料表建立叢集索引時的情況。相反的,當您對某資料行建立非叢集索引時,SQL Server 會在資料表上附加共用 (S) 鎖定,此舉雖然也會防止對基礎資料表進行資料更新,但是至少讓您能夠執行 SELECT 陳述式,因此您仍可讀取資料。

在建立叢集索引期間,如果資料表的讀取性是重要的,那麼您可以建立資料表的索引,並使其成為線上作業。以下就是這個命令:

CREATE UNIQUE CLUSTERED INDEX CLUST_IDX_SQLTIPS 
ON SQLTips (tip) with (ONLINE=ON) Go;

對資料表使用線上索引作業時,SQL Server 仍會在基礎資料表上,針對叢集索引放置 SCH-M 鎖定,或是針對非叢集索引放置共用 (S) 鎖定,但是只會進行一段非常短的時間,亦即在索引作業開始和結束的階段。所以在索引建立期間,此選項可以繼續讓使用者查詢和更新基礎資料表。但是請注意,線上索引建立/作業僅適用於 SQL Server 2005 Enterprise Edition。

答:會突然發生出乎預期的 CPU 瓶頸,伺服器上又毫無變更或額外的負荷時,有幾項可能的核心原因,但是其中一些常見的原因包括:未最佳化的查詢規劃、差勁的 SQL Server 設定、不適當的應用程式/資料庫設計,以及硬體資源不足。

在像這樣的情況下,第一件要做的事情就是辨識您的伺服器是否受 CPU 限制,如果是的話,請找出本機 SQL Server 系統上,成為 CPU 最大消耗者的陳述式。您可以使用效能監視器並查看 PROCESSOR:% PROCESSOR TIME 計數器,來判斷伺服器是否受 CPU 限制。如果您發現每個 CPU 所使用的時間值等於或大於百分之 75,就表示發生了 CPU 瓶頸。

您還應該查詢系統上稱為 SYS.DM_OS_SCHEDULERS 的動態管理檢視 (DMV),以查看可執行工作的數目,來監視 SQL Server 的排程器。非零的值表示工作必須等候其時間片段才能執行;此計數器的值如果太大,也是發生 CPU 瓶頸的徵兆。

您可以使用以下查詢來列出所有排程器,並且查看可執行工作的數目:

SELECT
 Scheduler_ID,
 Current_Tasks_Count,
 Runnable_Tasks_Count
FROM
 SYS.DM_OS_SCHEDULERS
WHERE
 Scheduler_ID < 255

若要取得前 50 項耗用 CPU 資源的 SQL 陳述式,請使用 [圖 1] 中的查詢。

Figure 1 前 50 大 CPU 資源耗用者

SELECT TOP 50 (a.total_worker_time/a.execution_count) AS [Avg_CPU_Time],
 Convert(Varchar,Last_Execution_Time) AS 'Last_execution_Time',
 Total_Physical_Reads,
 SUBSTRING(b.text,a.statement_start_offset/2,
 (case when a.statement_end_offset = -1 then len(convert(nvarchar(max), b.text)) * 2
 else
 a.statement_end_offset end - a.statement_start_offset)/2) AS Query_Text,
 dbname=Upper(db_name(b.dbid)),
 b.objectid AS 'Object_ID'
 FROM sys.dm_exec_query_stats a
 CROSS APPLY
 sys.dm_exec_sql_text(a.sql_handle) AS b
 ORDER BY
 [Avg_CPU_Time] DESC

問:我必須從磁帶復原 SQL Server 2005 的資料庫。在復原之後,使用者對資料庫所擁有的大部分權限都遺失了。可否告訴我在還原的期間,我做錯了什麼?資料都完好,但是權限都亂成一團。

答:最可能的情況是您未及時將主資料庫還原到同一時間點,並且使用者資料庫中的登入識別碼與目前的主資料庫不符。您必須將其同步。「移動資料庫時可從何處獲得協助」資訊看板列出了最有用的資源,以供您解決在還原或移動資料庫時所遭遇到的問題。

問:我開發了一個應用程式,其中的預存程序使用 SQL Server 2005 SP1 中的 OpenXML,將 XML 資料切換成關聯式資料表。XML 文件最大可為 5KB (平均為 2.5KB)。預存程序可供多次平行呼叫 (至多 50 次)。

我遇到非常嚴重的鎖定爭奪問題,我想它們可能是由 OpenXML 造成的。您認為如何?

答:對於在單一執行緒上切斷或轉換資料,雖然 OpenXML 可能比節點方法快速,但是節點方法通常會有更好的擴充性,特別是在平行使用的情況下。然而,如果您一定要使用 OpenXML,就應該遵循以下指引,來改善整體 OpenXML 的效能。

不要用相同的資料列模式呼叫 OpenXML 五次 (正如您在解決方案中所做的一樣),您應該將具相同資料列模式的所有資料,都擷取到暫存資料表中,然後再從暫存資料表中執行您的選取作業。請嘗試用 sp_xml_removedocument 盡早釋放記憶體。此外,最好還是避免使用萬用字元 (例如 * 和 //);而且盡可能提供明確的路徑,因為如此可提升查詢的效率。

問:DBCC SHRINKFILE 在我的伺服器上執行得實在很緩慢。請問在多處裡器的電腦上,是否能獲得較佳的效能?我該怎麼做才能改善這種情況?

答:DBCC SHRINKFILE 是單一執行緒的作業,這表示它無法利用多個 CPU。它會把頁面從檔案的後端移動到檔案的前端,一次移動一個頁面。而且壓縮 (正如其名) 並不會執行重組;事實上在許多情況下,壓縮還會造成邏輯的分散。

改善壓縮效能的一些方式,包括在叢集索引中移動頁面。如果您擁有堆積,並且這些堆積具有許多非叢集的索引,速度就可能相當緩慢 (相較於叢集索引的情況)。

另請注意,移動大型物件區塊 (LOB) 資料的頁面會很緩慢,因為必須讀取整個資料列的資料,才能找到 LOB 資料的根節點。

如果索引/資料表的大部分內容位於檔案的結尾,您就可以重建索引,使其移動到檔案的前端。重建索引會利用多個 CPU,並且在 bulk_logged 模式下可能使用比較少的記錄空間。然後您在執行壓縮時,它就會執行得更快。

如需壓縮作業的詳細資訊,請參考位於 blogs.msdn.com/sqlserverstorageengine/archive/2007/03/29/how-does-your-schema-affect-your-shrink-run-time.aspxblogs.msdn.com/sql-serverstorageengine/archive/2007/04/15/how-to-avoid-using-shrink-in-sql-server-2005.aspx 的內容。

移動資料庫時可從何處獲得協助

提示:變更通訊埠

任何熟悉 SQL Server 的人都知道,SQL Server 接聽的預設通訊埠編號是 1433。雖然 SQL Server 的命名執行個體係設定為使用動態通訊埠 (這表示在 SQL Server 執行個體啟動的時候,都可以選取任何可以使用的通訊埠),但是預設的 SQL Server 執行個體卻一律接聽通訊埠 1433。因此,如果您的伺服器也是接聽預設的通訊埠,而您未嚴密地保護它的安全,則伺服器有可能暴露在安全性風險中。但是您可以變更預設的通訊埠來對抗攻擊。以下是變更的方式。

開啟 [SQL Server 組態管理員],並且展開 [SQL Server 2005 網路組態],然後選取 [通訊協定]。接下來,按兩下 [TCP/IP]。TCP/IP 屬性的清單及其功能顯示於下列圖表中,請按照規定加以設定。

請注意,SQL Server 資料庫引擎可以在同一 IP 位址上接聽多個通訊埠,因此請以半形逗號,如 1433,1500,1501 的格式分隔,來分別列出您要使用的通訊埠。如果您想要設定單一 IP 位址接聽多個通訊埠,還必須在 [TCP/IP 內容] 對話方塊的 [通訊協定] 索引標籤上,將 [全部接聽] 參數設定為 [否]。

接下來用滑鼠右鍵按一下每個位址,再按一下 [內容] 指定您想要設定的 IP 位址。如果 [TCP 動態通訊埠] 對話方塊包含 0,這表示資料庫引擎正在接聽動態通訊埠,請刪除 0。在 [IP 內容] 區域內的 [TCP 通訊埠] 方塊中,輸入您希望此 IP 位址接聽的通訊埠編號,然後按一下 [確定]。在 [主控台] 窗格中,按一下 [SQL Server 2005 服務],並且在 [詳細資訊] 窗格中,用滑鼠右鍵按一下 [SQL Server (<執行個體名稱>)],然後按一下 [重新啟動],以停止並重新啟動 SQL Server。

在將 SQL Server 設定為接聽特定通訊埠之後,共有三種方式可供用戶端連接到此通訊埠。您可以在伺服器上執行 SQL Server 瀏覽器服務,用名稱來連接到資料庫引擎執行個體;您可以在用戶端建立一個別名,指定其通訊埠編號;或是您可以用程式設計的方式,將用戶端設計為利用自訂連接字串來連接。

屬性 描述
使用中 表示 SQL Server 正在接聽指定的通訊埠。不適用於 IPAll。
已啟用 啟用或停用這個連線。不適用於 IPAll。
IP 位址 檢視或變更此連線所使用的 IP 位址。列出電腦所使用的 IP 位址,以及 IP 回送位址 127.0.0.1。不適用於 IPAll。
TCP 動態通訊埠 如果動態通訊埠尚未啟用,即為空白。若要使用動態通訊埠,請設定為 0。
TCP 通訊埠 檢視或變更 SQL Server 接聽的通訊埠。根據預設,預設執行個體會接聽通訊埠 1433。此欄位僅限 2047 個字元。

感謝以下 Microsoft IT 專家回答本月的問題: Chad Boyd、Cindy Gross、John Hadden、Saleem Hakani、Stephen Jiang、Mahesh Nayak、Paul Randal 及 Wayne Yu。

© 2008 Microsoft Corporation and CMP Media, LLC. 保留所有權利;未經允許,嚴禁部分或全部複製.