I see. It turns out that the selectivity of "type" is highly variable - some types are very common and some are quite rare. What made me curious is that when I have an index on type and I look for the first few entries in ascending order, the query is very fast - it seems that it does the indexed search on type and then starts searching the matching rows in ascending order. For the descending order, it seems that it has to find all matching rows and then return the last one (I don't know for sure how it's working, but that seems to fit the performance measurements). Is there any way to have it use the index on type and then search the matching rows in descending order so no sorting is required? My confusion is that it seems to search in descending order when only the primary key is involved, but not when using an index, even if that index has DESC specified. As you say, I have put in the "+type" trick, and that speeds up my common case (where a matching type is nearby so the linear search isn't so bad), so now I'm in the much better situation of just worrying about the hypothetical case where it has to search a long way to find a matching type. Thanks, Jeff
D. Richard Hipp wrote: > On Jul 1, 2008, at 2:17 PM, Jeff Gibson wrote: > > >> I'm including a copy of Alexey's relevant message below. Unless I >> misunderstand, he has a test case that demonstrates that for the >> table: >> >> CREATE TABLE events (eid INTEGER PRIMARY KEY,type INTEGER) >> >> the query: >> >> SELECT events.* FROM events WHERE eid<=32619760 and type=22 ORDER BY >> eid DESC LIMIT 1; >> >> runs much faster if there is no index on type. The culprit seems to >> be >> the <= in conjunction with the descending ordering. If you change >> either, the query gets much faster. He tried the using indices >> events(type,eid) and events(type,eid desc). I also tried your >> original >> suggestion of just events(type) and got the same result. >> > > That would be a case of SQLite choosing a suboptimal index, which is > very different from ignoring an index all together, which is what your > original statement said. I see that if there is an index on > events(type) that index is used rather than the primary key. This is > because the query optimizer is assuming that type=22 is highly > selective. Running ANALYZE might help. But a sure-fire solution is > to change the query as follows: > > SELECT * FROM events > WHERE eid<=32619750 > AND +type=22 > ORDER BY eid DESC > LIMIT 1; > > Note the "+" operator in front of the "type" field in the WHERE > clause. This + size makes that term of the WHERE clause an > expression, rather than a constraint on a column, and this > disqualifies it from use by an index. That forces SQLite to use the > other query strategy, which is to use the integer primary key. > > Note that in this case, the correct index choice depends on the kind > of data contained in the table. If there is only a single row out of > 20 million for which type=22, but there are hundreds of thousands of > rows with eid<=32619750, then the use of the index on event(type) is > clearly the better strategy. Only when type=22 is a common occurrence > does it become better to use the integer primary key. SQLite does not > attempt to keep statistics on table contents, so it has no way of > knowing which approach is really better. It makes its best guess. In > this case, it happened to guess wrong. But, as I pointed out, a > programmer with higher-level knowledge of the table content can steer > SQLite toward the better choice with the judicious use of a "+" symbol. > > > D. Richard Hipp > [EMAIL PROTECTED] > > > > _______________________________________________ > sqlite-users mailing list > sqlite-users@sqlite.org > http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users > _______________________________________________ sqlite-users mailing list sqlite-users@sqlite.org http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users