Improve INSERT-per-second performance of SQLite

后端 未结 10 2126
忘掉有多难
忘掉有多难 2020-11-21 04:41

Optimizing SQLite is tricky. Bulk-insert performance of a C application can vary from 85 inserts per second to over 96,000 inserts per second!

Background:

相关标签:
10条回答
  • 2020-11-21 05:22

    Bulk imports seems to perform best if you can chunk your INSERT/UPDATE statements. A value of 10,000 or so has worked well for me on a table with only a few rows, YMMV...

    0 讨论(0)
  • 2020-11-21 05:24

    Several tips:

    1. Put inserts/updates in a transaction.
    2. For older versions of SQLite - Consider a less paranoid journal mode (pragma journal_mode). There is NORMAL, and then there is OFF, which can significantly increase insert speed if you're not too worried about the database possibly getting corrupted if the OS crashes. If your application crashes the data should be fine. Note that in newer versions, the OFF/MEMORY settings are not safe for application level crashes.
    3. Playing with page sizes makes a difference as well (PRAGMA page_size). Having larger page sizes can make reads and writes go a bit faster as larger pages are held in memory. Note that more memory will be used for your database.
    4. If you have indices, consider calling CREATE INDEX after doing all your inserts. This is significantly faster than creating the index and then doing your inserts.
    5. You have to be quite careful if you have concurrent access to SQLite, as the whole database is locked when writes are done, and although multiple readers are possible, writes will be locked out. This has been improved somewhat with the addition of a WAL in newer SQLite versions.
    6. Take advantage of saving space...smaller databases go faster. For instance, if you have key value pairs, try making the key an INTEGER PRIMARY KEY if possible, which will replace the implied unique row number column in the table.
    7. If you are using multiple threads, you can try using the shared page cache, which will allow loaded pages to be shared between threads, which can avoid expensive I/O calls.
    8. Don't use !feof(file)!

    I've also asked similar questions here and here.

    0 讨论(0)
  • 2020-11-21 05:24

    I coudn't get any gain from transactions until I raised cache_size to a higher value i.e. PRAGMA cache_size=10000;

    0 讨论(0)
  • 2020-11-21 05:28

    Use ContentProvider for inserting the bulk data in db. The below method used for inserting bulk data in to database. This should Improve INSERT-per-second performance of SQLite.

    private SQLiteDatabase database;
    database = dbHelper.getWritableDatabase();
    
    public int bulkInsert(@NonNull Uri uri, @NonNull ContentValues[] values) {
    
    database.beginTransaction();
    
    for (ContentValues value : values)
     db.insert("TABLE_NAME", null, value);
    
    database.setTransactionSuccessful();
    database.endTransaction();
    
    }
    

    Call bulkInsert method :

    App.getAppContext().getContentResolver().bulkInsert(contentUriTable,
                contentValuesArray);
    

    Link: https://www.vogella.com/tutorials/AndroidSQLite/article.html check Using ContentProvider Section for more details

    0 讨论(0)
  • 2020-11-21 05:34

    The answer to your question is that the newer SQLite 3 has improved performance, use that.

    This answer Why is SQLAlchemy insert with sqlite 25 times slower than using sqlite3 directly? by SqlAlchemy Orm Author has 100k inserts in 0.5 sec, and I have seen similar results with python-sqlite and SqlAlchemy. Which leads me to believe that performance has improved with SQLite 3.

    0 讨论(0)
  • 2020-11-21 05:40

    Avoid sqlite3_clear_bindings(stmt).

    The code in the test sets the bindings every time through which should be enough.

    The C API intro from the SQLite docs says:

    Prior to calling sqlite3_step() for the first time or immediately after sqlite3_reset(), the application can invoke the sqlite3_bind() interfaces to attach values to the parameters. Each call to sqlite3_bind() overrides prior bindings on the same parameter

    There is nothing in the docs for sqlite3_clear_bindings saying you must call it in addition to simply setting the bindings.

    More detail: Avoid_sqlite3_clear_bindings()

    0 讨论(0)
提交回复
热议问题