在有多個應用程式使用相同 SQL 登入帳號存取 SQL Server 資料庫時,經常會無法在 SQL Server 管理介面中分析連線來源到底是誰,例如同時有一個網站與另一個 Windows 服務同時都在運作並連接資料庫的時候。遇到這種情況如果當資料庫發生負載過重時經常無法有效區別出到底是哪個應用程式發生問題,這時就可以利用今天的技巧來協助分析。
一般來說要查詢 SQL Server 的連線狀況可以透過 sp_who 系統預存程序查詢出目前正與 SQL Server 建立連接的所有連線項目,你至少可以看到當下的執行狀態(status)、登入者帳號(loginname)、連線來源的主機名稱(hostname)、連接的資料庫(dbname)、對資料庫下達的 T-SQL 指令(cmd)、…等。
不過 sp_who 系統預存程序提供的資料非常有限,我們可以改用另一個 sp_who2 系統內部預存程序來取得更加完整的連線資訊,除了 sp_who 系統預存程序能查出的資訊外,還可以額外取得該連線佔用的 CPU 時間(CPUTime)、磁碟使用量(DiskIO) 以及今天的主角 應用程式名稱(ProgramName):
首先,我們先來看大多數連線字串的寫法:
標準安全性
Data Source=(local);Initial Catalog=myDataBase;User Id=myUsername;Password=myPassword;
信任式連線
Data Source=(local);Initial Catalog=myDataBase;Integrated Security=SSPI;
事實上在設定連線字串的時候還有一個較少人使用的 Application Name 參數,此連線參數用來定義連接至 SQL Server 的應用程式名稱,這裡所設定的 Application Name 參數就會顯示在 sp_who2 執行結果的 ProgramName 欄位上。
也就是說,當 SQL Server 連線數一多的時候,即便從不同應用程式過來的登入帳號(Login)都一樣,還是可以透過 ProgramName 所顯示的名稱來區別到底這個連線是從哪裡應用程式過來的。
如果我們將原本的連線字串修改一下,加上 Application Name 參數為 Website1 的話:
Data Source=.;Initial Catalog=myDB;User Id=myUser;Password=myPass;Application Name=Website1
這時將網站啟動與瀏覽幾頁,並到 Management Studio 執行 sp_who2 預存程序,即可發現差異:
在應用程式或網站中自訂 Application Name 參數還不止這個好處,甚至於你在執行 SQL Server Profiler 時也能利用該 ApplicationName 欄位進行篩選,這樣能夠大量減少在正式環境下分析大量查詢的負擔:
備註1
如果網站應用程式是在 Web Farm 的部署架構下運行,要釐清到底是哪壹台 Web 伺服器發生資料庫連線問題,也可以透過 sp_who2 查詢出連線資訊,並透過 HostName 欄位即可區分出到你是哪壹台伺服器的連線,在沒有多應用程式連線的情況下,通常不太需要設定 Application Name 參數。
備註2
sp_who2 一直都是「未公開文件」的內部版本,從 SQL Server 7.0 就有了,一直到 SQL Server 2008 R2 都還能使用,不過網路上也有許多人自行實做 sp_who3 的版本,這個版本寫的還不錯,不過若要在 SQL Server 2005 以上的版本要正常執行還需要將 nvarchar(255) 都修改成 nvarchar(max) 比較不會出問題。
相關連結