2

我正在使用Advantage Database Server v10和相應的ADO.NET提供程序。我發現AdsConnection.Close在執行INSERT/UPDATE查詢後需要很長時間。Advantage數據庫服務器插入/更新查詢性能問題

例如此示例

class Program 
{ 
    static void Main(string[] args) 
    { 
     var openTimer = new Stopwatch(); 
     var closeTimer = new Stopwatch(); 
     var executeTimer = new Stopwatch(); 

     for (int ix = 0; ix < 100; ix++) 
     { 
      openTimer.Start(); 
      using (var cnn = new AdsConnection(
       @"data source=...; ServerType=remote; user id=admin; password=...")) 
      { 
       cnn.Open(); 
       openTimer.Stop(); 


       executeTimer.Start(); 
       using (var cmd = cnn.CreateCommand()) 
       { 
        cmd.CommandText = "SELECT MAX(colUGId) FROM tblUserGroup"; 

        var id = (int)cmd.ExecuteScalar() + 1; 

        cmd.CommandText = "INSERT INTO tblUserGroup (colUGId, colName, colDesc) VALUES (:id, :name, :desc)"; 
        cmd.Parameters.Add("id", id); 
        cmd.Parameters.Add("name", "Name " + id); 
        cmd.Parameters.Add("desc", "Description " + id); 
        cmd.ExecuteNonQuery(); 
       } 
       executeTimer.Stop(); 


       closeTimer.Start(); 
      } 
      closeTimer.Stop(); 
     } 

     Console.WriteLine("Open: {0}; Execute: {1}; Close: {2}", openTimer.Elapsed, executeTimer.Elapsed, closeTimer.Elapsed); 
    } 
} 

輸出:

Open: 00:00:00.2361612; Execute: 00:00:15.3849932; Close: 00:00:05.4333431 

這是非常有趣的,爲什麼在瑣碎的指標,沒有任何觸發器的簡單表格100個INSERT操作需要15秒。但最重要的問題是:爲什麼Close需要這麼長時間?

任何想法?

UPDATE

只是試圖與SQL Server的同一。它運行在不同的工作站上,這比使用Advantage的工作站快一點。無論如何,我可以看到連接池可以工作(在SQL Server的情況下):

Open: 00:00:00.2279668; Execute: 00:00:00.0189551; Close: 00:00:00.0003487 
+1

您正在創建和處理AdsConnection類100次。爲什麼不打開一次,執行所有插入操作,然後關閉? –

+0

@BradM我認爲,連接池是爲了節省我的工作而發明的 –

+0

即。是正確的,連接池應該完全解決這個問題,另請參見:http://devzone.advantagedatabase.com/dz/webhelp/Advantage11.1/dotnet_advantage_net_data_provider_and_connection_pooling.htm –

回答

2

15秒絕對長。既然你提到索引,我相信你有必要的索引,但要確保在colUGId上有索引。如果該索引不存在,則每次運行時,select max查詢都需要全表掃描。如果桌子比較大,那可能是非常昂貴的。

雖然連接池確實消除了每次通過循環時獲取新連接的成本,但所示的代碼會導致涉及的表在每次迭代時都完全關閉。因此,服務器每次通過循環結束打開和關閉表(假設沒有其他用戶在執行此測試時打開表)。這肯定會增加成本,但我不知道爲什麼會導致報告的時間。

雖然它不回答這個問題,我跑上面確切的代碼(具有修飾當然連接字符串),併產生這些數字:

Open: 00:00:00.8909295; Execute: 00:00:01.4729069; Close: 00:00:01.4211188 

出於好奇,我然後移動的所述獲取連接在循環之外並再次運行。這使得表格在執行之間保持開放。它導致了這些數字:

Open: 00:00:00.1073400; Execute: 00:00:00.0802774; Close: 00:00:00.0270569 

另一件需要注意的代碼是,它不能重用任何預處理語句。特別是,SELECT和INSERT都使用相同的命令對象。這會導致語句在每次迭代中被解析和語義檢查。這當然不是一件大事,但它可以加起來。我使用兩個命令對象再次運行測試,並得到這些數字:

Open: 00:00:00.0835544; Execute: 00:00:00.0567687; Close: 00:00:00.0267799