6

I'm doing big batch inserts into an SQLite3 database and I'm trying to get a sense for what sort of performance I should be expecting versus what I'm actually seeing.

My table looks like this:

cursor.execute(
            "CREATE TABLE tweets(
             tweet_hash TEXT PRIMARY KEY ON CONFLICT REPLACE,
             tweet_id INTEGER,
             tweet_text TEXT)"
        )

and my inserts look like this:

cursor.executemany("INSERT INTO tweets VALUES (?, ?, ?)", to_write)

where to_write is a list of tuples.

Currently, with about 12 million rows in the database, inserting 50 000 rows is taking me around 16 minutes, running on a 2008 macbook.

Does this sound reasonable, or is there something gross happening?

8
  • Have you tried inserting multiple values in each query? Maybe not all of them at once, since you would have to create a very large string, but maybe 100 each? In my experience this improves insertion speed a lot. Commented Jul 25, 2013 at 20:02
  • @GustavLarsson: executemany is supposed to take advantage of preparing the query and streaming in the per-row columns already. Commented Jul 25, 2013 at 20:03
  • @GustavLarsson: How were you proposing creating multiple inserts? execute() and executemany() only allow for one statement. Commented Jul 25, 2013 at 20:04
  • 1
    i think something like for i in range(0,len(my_list),100):execute_many(qry,my_list[i:i+100]) at a guess Commented Jul 25, 2013 at 20:31
  • 2
    Does executemany use transactions? If not, sqlite will internally wrap each and every insert statement with an implicit transaction, which can cause a huge performance hit on bulk inserts. See these for a little more info: sqlite.org/faq.html#q19 or stackoverflow.com/questions/3852068/sqlite-insert-very-slow Commented Jul 25, 2013 at 21:24

1 Answer 1

8

As I understand the main reason of bad performance is time you waste to commit many SQLite transactions. What to do?

Drop the indexes, then

PRAGMA synchronous = OFF (or NORMAL)

Insert blocks of N rows (define N, try N=5000 to start). Before inserting block do

BEGIN TRANSACTION

after inserting do

COMMIT

See also http://www.sqlite.org/faq.html#q19

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.