首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

SQL Server 實戰經驗技巧大全:安裝、維護、效能、備份還原全覆蓋

     編輯:關於SqlServer

前言

凝聚多年 SQL Server 實戰經驗,涵蓋安裝疑難雜症、日常維護、效能調優、備份還原、安全性、疑難排解六大領域 20+ 實用技巧,每項皆經生產環境驗證。

一、安裝與修補篇

1. 安裝提示「有掛起的作業」解決方案

-- 登錄機碼清理法
REGEDIT → HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager
→ 右側 PendingFileRenameOperations → 刪除 → 重新安裝

原因:前次安裝/更新需重啟完成檔案置換,未重啟即再次執行安裝程式。

2. SP3/SP4 安裝報「TCP/IP Sockets: Specified SQL Server not found」

  • 用戶端網路公用程式 → 啟用協定 → **Named Pipes 移至第一順位**;
  • 登錄 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer\Client\ConnectTo → DSQUERY=DBNETLIB;
  • 停止 MSSQLSERVER 服務 → 執行安裝。

根因:SP3 安裝程式預設嘗試 TCP/IP 連線,但服務尚未啟動監聽。

二、資料庫維護篇

3. 兩種清除交易記錄膨脹方法

方法 A:簡單復原模式 + SHRINKFILE

BACKUP LOG DBName WITH NO_LOG  -- 截斷非作用中記錄
DBCC SHRINKFILE (DBName_Log, 10)  -- 目標 10MB

方法 B:完整復原模式(正規流程)

BACKUP LOG DBName TO DISK = 'path\log.trn'  -- 正規記錄備份
DBCC SHRINKFILE (DBName_Log, 10)

禁忌:TRUNCATE_ONLY/NO_LOG 會破壞備份鏈,完整模式嚴禁使用。

4. 刪除重複資料四板斧(無游標、秒級完成)

-- 1. 建立同結構暫存表
SELECT TOP 0 * INTO #Tmp FROM SourceTable;

-- 2. 加上唯一索引(忽略重複鍵)
CREATE UNIQUE INDEX IX_Tmp_Key ON #Tmp(KeyCol) WITH IGNORE_DUP_KEY;

-- 3. 複製資料(重複列自動忽略)
INSERT INTO #Tmp SELECT * FROM SourceTable;

-- 4. 覆蓋原表
TRUNCATE TABLE SourceTable;
INSERT INTO SourceTable SELECT * FROM #Tmp;
DROP TABLE #Tmp;

核心:IGNORE_DUP_KEY 讓重複鍵只產生警告不報錯,配合批次複製實現無游標去重。

5. 變更資料表擁有者(Schema 遷移)

-- 方法一:sp_changeobjectowner (舊版相容)
EXEC sp_changeobjectowner 'olduser.TableName', 'dbo';

-- 方法二:ALTER SCHEMA (SQL 2005+ 推薦)
ALTER SCHEMA dbo TRANSFER olduser.TableName;

三、效能調優篇

6. 索引維護另類技巧

  • DBCC DBREINDEX 離線重建 vs ALTER INDEX ... REBUILD 線上重建(企業版);
  • 填充因子 FILLFACTOR:高更新表設 80-90%,唯讀表 100%;
  • 統計資訊自動更新:AUTO_UPDATE_STATISTICS ON,大表配合 sp_updatestats 排程手動更新。

7. 全文檢索中文錯誤解決

-- 方法一:複製語斷詞檔
COPY chs*.* TO ...\MSSQL\FTDATA\SQLServer\Config\

-- 方法二:清空 noise.chs 並輸入特殊字元
ECHO @ > ...\MSSQL\FTDATA\SQLServer\Config\noise.chs

-- 最後:重新完整填充全文類別目錄

四、備份與還原篇

8. 無記錄檔還原資料庫兩則

  • 方法一:sp_attach_single_file_db 僅附加 MDF(前提:正常關閉、無作用中交易);
  • 方法二:建立同名空資料庫 → 停止服務 → 覆蓋 MDF → 啟動服務 → DBCC REBUILD_LOG(高風險,最後手段)。

9. 利用記錄備份還原至時間點

RESTORE DATABASE DBName FROM DISK='Full.bak' WITH NORECOVERY;
RESTORE LOG DBName FROM DISK='Log1.trn' WITH NORECOVERY;
RESTORE LOG DBName FROM DISK='TailLog.trn' WITH STOPAT='2024-01-15 14:30:00', RECOVERY;

10. 資料庫檔案損壞緊急修復

ALTER DATABASE DBName SET SINGLE_USER;
DBCC CHECKDB('DBName', REPAIR_ALLOW_DATA_LOSS);  -- 最後手段,資料遺失風險
ALTER DATABASE DBName SET MULTI_USER;

五、安全性篇

11. 存儲過程加密與解密

-- 建立加密程序
CREATE PROC usp_Secret WITH ENCRYPTION AS SELECT * FROM SecretTable;

-- 解密(需 DAC 連線、系統表查詢,僅供緊急救援)
-- 參考 sp_decrypt 社群腳本

12. 移除危險擴展預存程序

EXEC sp_dropextendedproc 'xp_cmdshell';
EXEC sp_dropextendedproc 'xp_regwrite';
-- 參考文章 84485 完整清單

六、疑難排解篇

13. PRINT 陳述式導致用戶端視窗自動關閉的怪異 Bug

現象:特定用戶端機器執行含 PRINT 的預存程序時,應用程式視窗無異常即關閉。

根因:舊版 ODBC/OLE DB 驅動程式處理 PRINT 回傳的資訊訊息 (SQL_INFO) 時觸發未處理例外。

解決:生產環境預存程序**嚴禁保留 PRINT/RAISERROR (低嚴重度) 調試碼**;改用記錄表寫入除錯資訊。

14. 連線池耗盡排查

-- 檢視連線池狀態
SELECT * FROM sys.dm_exec_connections;  -- SQL 2005+
-- SQL 2000 用 DBCC USEROPTIONS / sp_who

應用端確認:Connection.Close() / Dispose() 確實執行、連接字串一致性(連線池分組依賴字串完全相同)。

15. 死鎖分析與解決

  • 追蹤旗標 1204/1222 記錄死鎖圖至錯誤日誌;
  • 統一存取順序(資料表、索引鍵)、縮短交易範圍、避免使用者互動在交易中;
  • 啟用 READ_COMMITTED_SNAPSHOT (SQL 2005+) 減少讀寫封鎖。

七、開發最佳實務

16. 分頁查詢三種模式

-- SQL 2000:巢狀 TOP
SELECT TOP 10 * FROM (
    SELECT TOP 10 * FROM (
        SELECT TOP 1010 * FROM DocDetail ORDER BY LastModDate ASC, ID ASC
    ) T1 ORDER BY LastModDate DESC, ID DESC
) T2 ORDER BY LastModDate ASC, ID ASC;

-- SQL 2005+:ROW_NUMBER()
SELECT * FROM (
    SELECT ROW_NUMBER() OVER (ORDER BY LastModDate, ID) AS RN, *
    FROM DocDetail
) T WHERE RN BETWEEN 1001 AND 1010;

17. 隨機抽樣 N 筆

-- SQL Server
SELECT TOP 10 * FROM LargeTable ORDER BY NEWID();

-- Access
SELECT TOP 10 * FROM Table ORDER BY RND(ID);

18. 非空值唯一約束(允許多筆 NULL)

-- SQL 2000:觸發器實作
CREATE TRIGGER tr_UniqueNonNull ON TableName
FOR INSERT, UPDATE AS
IF (SELECT MAX(cnt) FROM (
    SELECT COUNT(*) AS cnt FROM TableName t JOIN inserted i ON t.KeyCol = i.KeyCol
    WHERE t.KeyCol IS NOT NULL GROUP BY i.KeyCol
) x) > 1
    ROLLBACK TRAN;

-- SQL 2008+:篩選索引
CREATE UNIQUE INDEX IX_UniqueNonNull ON TableName(KeyCol) WHERE KeyCol IS NOT NULL;

結語

技巧源於實戰,實戰驗證技巧。本文 18 項技巧覆蓋 SQL Server 全生命週期,**建議收藏建立個人知識庫**,遇到對應場景快速檢索。記住:最好的技巧是預防問題發生的架構設計,其次是快速定位解決問題的診斷流程,最後才是緊急救援的手術刀。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved