Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SQLite Insert very slow?

I recently read about SQLite and thought I would give it a try. When I insert one record it performs okay. But when I insert one hundred it takes five seconds, and as the record count increases so does the time. What could be wrong? I am using the SQLite Wrapper (system.data.SQlite):

dbcon = new SQLiteConnection(connectionString); dbcon.Open();  //---INSIDE LOOP   SQLiteCommand sqlComm = new SQLiteCommand(sqlQuery, dbcon);   nRowUpdatedCount = sqlComm.ExecuteNonQuery();   //---END LOOP  dbcon.close(); 
like image 364
Verve Innovation Avatar asked Oct 03 '10 23:10

Verve Innovation


People also ask

Why is SQLite so slow?

The SQLite docs explains why this is so slow: Transaction speed is limited by disk drive speed because (by default) SQLite actually waits until the data really is safely stored on the disk surface before the transaction is complete. That way, if you suddenly lose power or if your OS crashes, your data is still safe.

How fast is SQLite?

The chart shows that on Windows10, content can be read from the SQLite database about 5 times faster than it can be read directly from disk. On Android, SQLite is only about 35% faster than reading from disk.

Which is better SQLite or PostgreSQL?

SQLite doesn't perform well when it comes to user management. It also lacks the ability to handle simultaneous access by multiple users. PostgreSQL performs very well in managing users. It has well-defined permission levels for users that determine what operations they can perform in the database.

How many records can SQLite handle?

The theoretical maximum number of rows in a table is 264 (18446744073709551616 or about 1.8e+19). This limit is unreachable since the maximum database size of 281 terabytes will be reached first.


2 Answers

Wrap BEGIN \ END statements around your bulk inserts. Sqlite is optimized for transactions.

dbcon = new SQLiteConnection(connectionString); dbcon.Open();  SQLiteCommand sqlComm; sqlComm = new SQLiteCommand("begin", dbcon); sqlComm.ExecuteNonQuery();  //---INSIDE LOOP   sqlComm = new SQLiteCommand(sqlQuery, dbcon);   nRowUpdatedCount = sqlComm.ExecuteNonQuery();   //---END LOOP sqlComm = new SQLiteCommand("end", dbcon); sqlComm.ExecuteNonQuery();  dbcon.close(); 
like image 194
tidwall Avatar answered Sep 23 '22 05:09

tidwall


I read everywhere that creating transactions is the solution to slow SQLite writes, but it can be long and painful to rewrite your code and wrap all your SQLite writes in transactions.

I found a much simpler, safe and very efficient method: I enable a (disabled by default) SQLite 3.7.0 optimisation : the Write-Ahead-Log (WAL). The documentation says it works in all unix (i.e. Linux and OSX) and Windows systems.

How ? Just run the following commands after initializing your SQLite connection:

PRAGMA journal_mode = WAL PRAGMA synchronous = NORMAL 

My code now runs ~600% faster : my test suite now runs in 38 seconds instead of 4 minutes :)

like image 44
david_p Avatar answered Sep 19 '22 05:09

david_p