2014-02-05 65 views
1

我知道插入/更新多行時SQLite的'問題',但這不是這裏的情況。SQLite更新一個記錄是非常(相對)慢

我正在更新一行中的一個字段,由PK索引,在表中有〜250條記錄。查詢總是需要〜200毫秒。這聽起來很少,但它很大。

爲什麼1很簡單UPDATE查詢需要200毫秒?所有的閱讀都很快。

我已經試過:

  • BEGINCOMMIT - 沒有變化,因爲它只是1個語句
  • PRAGMA journal_mode=PERSIST - 沒有變化,顯然是磁盤IO是沒有問題嗎?
  • 去除UPDATE陳述 - 奇妙的作品的時間!但它不是很執着

比較到MySQL在同一系統上:0.6ms在一個非常類似的數據庫。

我不需要交易安全(ACID?)或任何你稱之爲的東西。如果在查詢過程中計算機崩潰,我很好,輸了全部的變化。 MySQL(InnoDB)有一個選項:innodb_flush_log_at_trx_commit。 SQLite有類似的東西嗎?

我正在使用sqlite-3.7.9,如果這很重要。

+0

您是否嘗試過設置[VACUUM](http://www.sqlite.org/lang_vacuum.html)參數? – ldav1s

+0

'VACUUM'會重建數據庫?但它是一個很小的分貝(270 kb)。更新的字段未編入索引。我將如何執行VACUUM,只是爲了嘗試? – Rudie

+0

我做了一個VACUUM,現在db文件稍小=)就是這樣。沒有下面的答案,它仍然是一個非常緩慢的'更新'。 – Rudie

回答

6

是,SQLite的有一個像MySQL的innodb_flush_log_at_trx_commit一個選項:

PRAGMA synchronous=OFF 

,它就像一個魅力。沒有ACID,是速度。出於一些不可思議的原因,UPDATE現在需要< 1ms。

另外也提高了journal_mode

PRAGMA journal_mode=MEMORY 
or 
PRAGMA journal_mode=OFF 

兩者都非常快,不耐酸。回滾不是問題,所以在這種情況下兩者都很好。 OFF是最快的,因爲它根本不創建日誌(?)。

+1

使用'synchronous = OFF'或'journal_mode = OFF'時要小心,因爲它可以[損壞數據庫](https://sqlite.org/howtocorrupt.html)。 –

0

SQLite是處理輕量級數據集的好選擇。是的,在插入/更新數據時,它比任何數據庫要慢得多。可以通過自己提交查詢來加速這些操作。請通過下面的演示代碼。我已經用JDBCTemplate Spring框架引用了JAVA代碼來執行我的數據庫操作。請使用try-catch bolck處理所需的例外

conn = DataSourceUtils.getConnection(jdbcTemplate.getDataSource()); 
conn.setAutoCommit(false); 
PreparedStatement stmt = conn.prepareStatement(query_string); 
for(Object[] temp:argsListForInsertQuery) 
{ 
    stmt.setString(1, (String)temp[0]); 
    stmt.setString(2, (String)temp[1]); 
    stmt.setString(3, (String)temp[2]); 
    stmt.setString(4, (String)temp[3]); 
    stmt.addBatch(); 
} 
stmt.executeBatch(); 
conn.commit(); 
conn.setAutoCommit(true); 
conn.close(); 
+0

我知道一個。 SQLite網站談論其插入速度與交易。儘管我的用例只有1個查詢。或者幾個無關的。 (不應該'conn'有一個類型?) – Rudie