上次 [C#] SQL 資料庫 Connection Pool 連線池觀念釐清 有提到可以開啟 Connection Pool 來減少開啟連線的效能耗損,但最近發現有 Stored Procedure 執行後沒有手動 Drop Temp Table,而 .NET 又將連線丟回 Pool 裡面造成 Temp Table 沒有被正常釋放的問題,下面來測試看看是不是真的會有這種情況發生。
正常情況下 Temp Table 的生命週期為一個 Connection,當 Connection 結束時將會回收中間使用到的暫存資源,但是 .NET 內建的 Connection Pool 的功能讓 Connection 重複利用且沒有關閉,如果是 Web Applicetion 或是 Windows Service 沒有手動 Drop Temp Table 就會發生資源被占用的問題。
這邊為了測試我將 Pooling 設為 True 並將 MinPoolSize 設為 100 更容易看出差異
程式碼:
static void Main(string[] args) { SqlConnectionStringBuilder sqlStrBuilder = new SqlConnectionStringBuilder(); sqlStrBuilder.DataSource = "192.168.245.137"; sqlStrBuilder.UserID = "sa"; sqlStrBuilder.Password = "Zxcv#1234"; sqlStrBuilder.InitialCatalog = "master"; sqlStrBuilder.Pooling = true; sqlStrBuilder.MinPoolSize = 100; string connectionString = sqlStrBuilder.ToString(); for (int i = 0; i < 100; i++) { string result = ExecuteSql(connectionString, i); Console.WriteLine(result); } Console.ReadKey(); } static string ExecuteSql(string connectionString, int i) { string tempTableName = $"#{Guid.NewGuid().ToString().Replace("-", string.Empty)}"; var sb = new StringBuilder(); sb.AppendLine($"SELECT '{i} - {tempTableName}' AS col INTO {tempTableName}"); sb.AppendLine($"SELECT col FROM {tempTableName}"); using (var sqlConnection = new SqlConnection(connectionString)) { string sql = sb.ToString(); return sqlConnection.ExecuteScalar<string>(sql); } }
Temp Table 占用狀態:
結論:
只要不結束應用程式這些 Temp Table 就不會被釋放,如果資料量大的話會造成硬碟空間被大量占用甚至出現吃滿的狀況。
從這件事可以了解使用 Temp Table 完畢後記得要手動 Drop 掉,不要去依賴預設的回收機制不然可能會有效能問題。