Squeezing Performance from SQLite: EXPLAINing the Virtual Machine
medium.com
medium.com
> P.P.S. If you were paying attention, you might have noticed some funkiness going on with my numbers in the charts as well as the records per second breakdowns. They fluctuate kind of widely between tests. For example: the time it took to insert 100,000 track records within a transaction using db.insert() in the first two experiments went from 91.552 seconds all the way up to 145.607 seconds.
I do wish he would have also used explain to analyse what these inserts were doing really for further insight into SQLite. To be honest, I am left wondering how much of what is being observed is specific to the Java/Android/SQLite environment and how much is actually core SQLite behavior.
Also, another nit specific to the article submitted [1]... The title is a bit inaccurate imo. The article demonstrates how to understand the EXPLAIN output, but it doesn't really explain (no pun intended) how to actually implement optimisations using this information. To me that isn't obvious. Would we have to change the SQLite source to implement a better query plan? Is there a configuration? How do we make use of this explain output to come up with a better result? Without that, I think the article lacks the "Squeezing Performance" part. I read the other articles in the series as well, and none of them use explain information to make optimisations either.
[0] https://medium.com/@JasonWyatt/squeezing-performance-from-sq...
[1] https://medium.com/@JasonWyatt/squeezing-performance-from-sq...
- why did it choose not to use an index?
- why does it need to do a scan of another table (oh there is FK)
- which part of the query plan is actually the expensive one.
For that you need to go to something like this:
https://github.com/asutherland/grok-sqlite-explain
http://www.visophyte.org/blog/2010/04/06/performance-annotat...
It's not exactly the same, but Postgres includes an LLVM-based JIT that compiles queries for reuse[1].
[1]: https://www.postgresql.org/docs/current/jit-reason.html
I don't see the NOOP in the article, but you do see these in sqlite when they, for example, have a struct of opcodes do dual duty for something like open-for-reading and open-for writing, where the struct has this:
/* One of the following two instructions is replaced by an OP_Noop. */
{OP_OpenRead, 0, 0, 0}, /* 3: Open cursor 0 for reading */
{OP_OpenWrite, 0, 0, 0}, /* 4: Open cursor 0 for read/write */