2011-06-09 72 views
0

我遇到了一個問題,其中提交的時間開始採取 越來越長。我們正在談論250毫秒的訂單,表 約2萬行,光盤大小約2-3mb。而且情況越來越糟糕。我已經跟蹤了 的性能問題,直到與索引有關。幾乎是 就好像sqlite在每次提交時都創建索引一樣。該提交包含 100個插入。我已經制作了一個儘可能小的程序,我可以在 中重現問題,並嘗試在Linux上運行該程序。 有問題似乎沒有發生。WAL和截斷日記模式存在問題。當我使用內存數據庫而不是文件時,問題似乎不存在 。我已經嘗試了版本號爲3.6.23.1和3.7.6.3的 。sqlite提交性能問題與索引

在我遇到問題的Windows上,我在C# 程序中運行sqlite。我已經在 System.Date.Sqlite包裝器中檢查了事務支持的實現,它絕對沒有其他任何其他 而不僅僅是一個COMMIT。可惜我沒有Windows編譯器的C編譯器 ,所以我不能在運行包裝器時檢查它,但它應該是 相同。

System.IO.File.Delete("test.db"); 

var db_connection = new SQLiteConnection(@"Data Source=test.db"); 

db_connection.Open(); 

using (var cmd = db_connection.CreateCommand()) 
{ 
    cmd.CommandText = "CREATE TABLE test (id integer primary key, dato integer)"; 
    cmd.ExecuteNonQuery(); 
    cmd.CommandText = "CREATE INDEX i on test(dato)"; 
    cmd.ExecuteNonQuery(); 
} 

SQLiteTransaction trans = null; 

List<string> paths = new List<string>(); 

var random = new Random(); 

for (var j = 0; j < 150; ++j) 
{ 
    for (var i = 0; i < 1000; ++i) 
    { 
     if (i % 100 == 0) 
     { 
      trans = db_connection.BeginTransaction(); 
     } 

     using (var cmd = db_connection.CreateCommand()) 
     { 
      cmd.CommandText = String.Format("INSERT INTO test (dato) values ({0})", random.Next(1, 100000000)); 
      cmd.ExecuteNonQuery(); 
     } 

     if (i % 100 == 99 && trans != null) 
     { 
      var now = DateTime.Now; 

      trans.Commit(); 
      trans.Dispose(); 

      System.Console.WriteLine("commit {0}", (DateTime.Now - now).TotalMilliseconds); 
     } 
    } 
} 
+0

看來,問題與隨機數的插入。如果我改變它插入j * 1000 + i,性能很好。但是當你不能預先定好你的結果以便它們適合整齊時,你做了什麼?在完成添加所需元素之前,是否禁用索引? – 2011-06-09 19:14:25

回答

0

你嘗試減少硬盤存取,例如創建任何表之前添加此命令:

cmd.CommandText = "PRAGMA locking_mode = EXCLUSIVE"; 
cmd.ExecuteNonQuery(); 

提供了您的應用程序允許對數據庫的獨佔鎖定。

還可以幫助:

PRAGMA Synchronous=OFF