使用SQLite 3.19.2,我遇到了一个奇怪的情况。
在我的应用程序中运行时,我的应用程序执行的其中一个查询需要很长的时间(100+秒)。使用sqlite3 shell,相同的查询需要0.5s。
我正在使用自定义的SQLite构建,静态链接到我的应用程序中。shell的版本来自我的自定义编译,所以这不是编译的问题。
我使用的是多个线程,但是从那以后,我成功地复制了这个问题--单线程的。
使用perf,我确定大部分的CPU时间都花在sqlite3VdbeExec上,而不是在我的任何代码中(例如,读取每个返回行的字段的代码)。
这个查询是带有绑定参数的sqlite3_prepare_v2d,我在下面复制了这个查询,以及一个类似的查询,它没有显示出性能问题。
还有其他人见过这样的东西吗?
慢速查询(应用程序中的100+s,外壳中的0.5s ):
SELECT DISTINCT
Track.*
FROM
TrackGenres,
TrackFirstArtist,
Track
WHERE
TrackFirstArtist.id = Track.id AND
TrackGenres.id = Track.id AND
TrackGenres.genreID = 328
ORDER BY
(CASE WHEN 1 = 1 THEN TrackFirstArtist.artistName COLLATE ENGLISH END) ASC,
(CASE WHEN 1 != 1 THEN TrackFirstArtist.artistName COLLATE ENGLISH END) DESC
LIMIT 50
OFFSET 0;查询计划(对于在应用程序中运行还是在shell中运行,计划是相同的):
2 0 0 SEARCH TABLE TrackGenre USING COVERING INDEX sqlite_autoindex_TrackGenre_1 (genreID=?)
3 0 1 SEARCH TABLE WorkGenre USING COVERING INDEX sqlite_autoindex_WorkGenre_1 (genreID=?)
3 1 0 SEARCH TABLE TrackWork USING COVERING INDEX sqlite_autoindex_TrackWork_1 (workID=?)
1 0 0 COMPOUND SUBQUERIES 2 AND 3 USING TEMP B-TREE (UNION)
4 0 0 SCAN TABLE TrackArtist USING INDEX idx_TrackArtist_trackID
4 1 1 SEARCH TABLE Artist USING INTEGER PRIMARY KEY (rowid=?)
0 0 0 SCAN SUBQUERY 1
0 1 2 SEARCH TABLE Track USING INTEGER PRIMARY KEY (rowid=?)
0 2 1 SEARCH SUBQUERY 4 USING AUTOMATIC COVERING INDEX (id=?)
0 0 0 USE TEMP B-TREE FOR DISTINCT
0 0 0 USE TEMP B-TREE FOR ORDER BY类似的查询( app中的0.5s,shell中的0.5s):
SELECT
COUNT (Track.id)
FROM
TrackGenres,
TrackFirstArtist,
Track
WHERE
TrackFirstArtist.id = Track.id AND
TrackGenres.id = Track.id AND
TrackGenres.genreID = 328 AND
( TrackFirstArtist.artistName >= 'a' AND TrackFirstArtist.artistName < 'b' );发布于 2017-08-04 20:44:22
我相信这是SQLite中的一个bug。我在准备好的语句中使用查询时,一直跟踪到ORDER BY子句中的ORDER BY语句。
当我删除其中一条或另一条语句时,查询再次快速运行。校对没有什么区别。
对于准备好的语句来说,这似乎不是一个普遍的问题,我还有其他类似结构的查询,它们正常工作。因此,我无法创建一个简单的、可复制的示例来说明这个问题。
最后,我不得不手动替换查询中的变量来解决这个问题,以避免使用准备好的语句。
https://stackoverflow.com/questions/45354288
复制相似问题