Search code examples
sqliteslickpragma

Scala Slick 2.0 and SQlite3 insert speed and PRAGMA


This questions is similar to these:

I have to index certain features from the Wikipedia XML dump. The parsing is fast. However, insert is slow.

Switching off indexing doubled the speed.

I batch insert like this:

    articles.grouped(5000)
           .foreach {
              batch: IterableView[(Article, List[Category], List[Link]), Iterable[_]] =>
                //Save each batch in one transaction
                database withTransaction {
                 implicit session =>
                   for(i <- batch) {
                     articles += i._1
                     categories ++= i._2
                     links ++= i._3
                   }

               }
            }

I read that journal_mode = MEMORY and synchronous = off increase the insert speed. How do I set these with slick? I am using c3p0 as a connection pool and added PRAGMA journal_mode = MEMORY to preferredTestQuery. I don't believe this is the right way to set these options.

Thanks for your help!


Solution

  • It seems like you are reading data once, locally. You could just not use transactions at all and use withSession instead. And if you still need a pragma you can set it via plain SQL. You probably want to reset the pragma after use to not leave a side-effect.

    import scala.slick.jdbc.StaticQuery.interpolation
    
    database withSession {
      implicit session =>
      sqlu"PRAGMA synchronous=OFF".execute
      articles.grouped(5000)
             .foreach {
                batch: IterableView[(Article, List[Category], List[Link]), Iterable[_]] =>
                  //Save each batch in one transaction
                   for(i <- batch) {
                     articles += i._1
                     categories ++= i._2
                     links ++= i._3
                   }
               }
    }
    

    Also interesting to know is that not only database has a withTransaction method, but also session. So you can do session.withTransaction within a withSession block re-using the same connection.