Comment #32 on issue 3847 by
manderss...@gmail.com: Clementine slow with
sqlite 3.8
http://code.google.com/p/clementine-player/issues/detail?id=3847
It was revision 4c23072bef94 that introduced the problem for me. I'm using
archlinux where the distro provided package for 1.2.1 does not include any
patches. I therefore assume that it uses the bundled sqlite that was
removed in 4c23072bef9.
I have compiled the git version of Clementine myself both with and without
the patch. For the unpatched build the library search gets really slow with
sqlite 3.8.1 but if I install sqlite 3.7.17 it returns to normal speed.
I'm using the official arch Linux packages for both sqlite versions. The
patched Clementine is equally fast with both versions.
The timings where I provided were taken directly from the sqlite shell with
a copy of my Clementine database which contains 7800 rows in the songs
table.
If I run SELECT statements with WHERE clauses on the effective_compilation
column there are no noticible speed differences e.g:
sqlite> .version
SQLite 3.8.1 2013-10-17 12:57:35 c78be6d786c19073b3a6730dfe3fb1be54f5657a
sqlite> SELECT Count(DISTINCT Artist) FROM songs WHERE
effective_compilation = 0 AND unavailable = 0;
334
CPU Time: user 0.060000 sys 0.006666
sqlite> SELECT Count(DISTINCT Artist) FROM songs WHERE
effective_compilation LIKE 0 AND unavailable = 0;
334
CPU Time: user 0.040000 sys 0.026667
The problem arises when we JOIN with the songs_fts table as in the
following queries:
sqlite> .version
sqlite> SELECT Count(DISTINCT artist) FROM songs INNER JOIN songs_fts AS
fts ON songs.ROWID = fts.ROWID WHERE fts.songs_fts MATCH "w*" AND
effective_compilation = 0 AND unavailable = 0;
203
CPU Time: user 21.463332 sys 0.013334
sqlite> SELECT Count(DISTINCT artist) FROM songs INNER JOIN songs_fts AS
fts ON songs.ROWID = fts.ROWID WHERE fts.songs_fts MATCH "w*" AND
effective_compilation LIKE 0 AND unavailable = 0;
203
CPU Time: user 0.016667 sys 0.013333
As you can see there is a considerable difference in speed when I
use "LIKE" instead of "=".
For sqlite 3.7.17, the speed of the above queries is about the same:
sqlite> .version
SQLite 3.7.17 2013-05-20 00:56:22 118a3b35693b134d56ebd780123b7fd6f1497668
sqlite> SELECT Count(DISTINCT artist) FROM songs INNER JOIN songs_fts AS
fts ON songs.ROWID = fts.ROWID WHERE fts.songs_fts MATCH "w*" AND
effective_compilation = 0 AND unavailable = 0;
203
CPU Time: user 0.026667 sys 0.006667
sqlite> SELECT Count(DISTINCT artist) FROM songs INNER JOIN songs_fts AS
fts ON songs.ROWID = fts.ROWID WHERE fts.songs_fts MATCH "w*" AND
effective_compilation LIKE 0 AND unavailable = 0;
203
CPU Time: user 0.026667 sys 0.006666
In order to make the above queries to run in the sqlite shell I had to make
a library of the Clementine's unicode tokenizer and load it into the shell.
You can avoid this by creating a copy of songs_fts using the simple
tokenizer and run the queries against this table instead. The speed
difference will be of the same order of magnitude.