
Then the table itself will be involved only for fetching those 200 rows that are to be displayed. The logic behind the queries is to use only the index for the derived table calculations (finding the max(retreival-time) for every seriesName and then order by and do the offset-limit thing.) Or (variation) using the PK as well, with an index on (seriesName, retreivalTime, dbId) and query: SELECT d.dbId, It won't be super fast but probably more efficient than what you have: SELECT d.dbId,ĪND di.max_retreivalTime = d.retreivalTime Here is a suggestion: add an index on (seriesName, retreivalTime) and try this query. My current thoughts are a commit-hook that updates a separate table that is used to track only unique items, but that seems like overkill. But it looks like its not working, which makes sense based on the following note in the documentation: If this option is defined, then it must also be defined when using the lemon tool to generate a parse.c file. Insert performance is not critical here, so if I need to create an additional index or two, that's fine. Based on Mithgol s tip, I took a naive stab at a pull request ( 699). How can I optimize this query? I can provide the raw query operations if needed. That would have somewhat poor performance for cases where OFFSET is large, but that happens very rarely in this application. The most basic usage of the ORDER BYclause is to follow it with the name of the column we want to sort by. If I drop the GROUP BY, it behaves as expected: sqlite> EXPLAIN QUERY PLAN SELECT dbId, dlState, retreivalTime, seriesName FROM DataItems ORDER BY retreivalTime DESC LIMIT 200 OFFSET 0 Ġ|0|0|SCAN TABLE DataItems USING INDEX DataItems_time_indexīasically, my naive assumption would be that the best way to perform this query would be to walk backwards from latest value in retreivalTime, and every time a new value for seriesName is seen, append it to a temporary list, and finally return that value. FROM (SELECT FROM db. The index on seriesName is COLLATE NOCASE, if that's relevant. However, EXPLAIN QUERY PLAN seems to indicate they're not being used: sqlite> EXPLAIN QUERY PLAN SELECT dbId, sqlite> SELECT name FROM sqlite_master WHERE type='index' ORDER BY name ĭataItems_time_index // This is the index on retreivalTime. I have indexes on both seriesName and retreivalTime. It takes approximately 800 milliseconds to execute on a table with ~67K rows. But it looks like it's not working, which makes sense based on the following note in the documentation: If this option is defined, then it must also be defined when using the 'lemon' tool to generate a parse.c file. Where limit is typically ~200, and offset is 0 (they drive a pagination mechanism).Īnyways, right now, this one query is completely killing my performance. Based on Mithgol 's tip, I took a naive stab at a pull request ( 699). Right now, I am generating some content to display using the following query: SELECT dbId, The only case where it seems that using SORT and LIMIT would be desirable would be, as mson mentioned, where you're writing a general operation that finds the top or bottom N values from arbitrary columns and it's not worth writing out the special-case operation.I have a little web-application that is using sqlite3 as it's DB (the db is fairly small). It looks like MIN() is the way to go - it's faster in the worst case, indistinguishable in the best case, is standard SQL and most clearly expresses the value you're trying to get. The actual performance impact is probably negligible. Looking at the output of explain, however, it looks like MIN() is able to simply pluck the smallest value from the index ('Select tables optimized away' and 'NULL' rows) whereas the SORT and LIMIT still needs needs to do an ordered traversal of the index (106,000 rows). If, however, you're looking at an indexed column, the difference is harder to notice (meaningless data point is 0.00s in both cases).

Lower case letters are used to represent user-defined words. 84s against a 106,000 row table on my dev server. Upper case letters are used to represent reserved words. If run against a large table, there would likely be a significant difference in percieved performance.

#Sqlite order by and limit top and bottom how to#
Let's try age: SELECTsex,age,nameFROMpeopleORDERBYageLIMIT3 Where does ORDER BY fit How to remember where ORDER BYfits in the query syntax so far Well, we know that LIMITwill be the last part of virtually any statement. Using SORT and LIMIT requires a filesort. The most basic usage of the ORDER BYclause is to follow it with the name of the column we want to sort by.
#Sqlite order by and limit top and bottom full#
In the worst case, where you're looking at an unindexed field, using MIN() requires a single full pass of the table.
