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.
    Thanks,
    Jeff


D. Richard Hipp wrote:
> On Jul 1, 2008, at 1:24 PM, [EMAIL PROTECTED] wrote:
>   
>> Is it a problem in sqlite that it will only optimize:  "WHERE
>> primary_key<=X ORDER BY primary_key DESC" if it's not using an index?
>> Is it supposed to?
>>     
>
> It would be a problem if it where the case.  But in every test I have  
> tried, SQLite does in fact use an index on WHERE pk<=X ORDER BY pk  
> DESC.  If you can demonstrate a case where it does not, we will fix it.
>
> D. Richard Hipp
> [EMAIL PROTECTED]
>
>
>
> _______________________________________________
> sqlite-users mailing list
> sqlite-users@sqlite.org
> http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users
>   


Alexey Pechnikov wrote:
> Really, there is problem with multi-column indexes. You must use only primary 
> key index for ">=" where clause and "ASC" sorting and "<=" where clause and 
> DESC sorting. 
>
>
> 1. I try with primary key:
>
> #!/usr/bin/tclsh
> package require sqlite3
> sqlite3 db index_order.db
> db eval {DROP TABLE IF EXISTS events}
> db eval {CREATE TABLE events (eid INTEGER PRIMARY KEY,type INTEGER)}
> db transaction {
>     for {set i 0} {$i<100000000} {incr i} {
>         set type [expr {$i % 50}]
>         db eval {insert into events values ($i,$type)}
>     }
> }
> db close
>
> So, "type" is equal ("eid" mod 50).
>
> sqlite> SELECT events.* FROM events WHERE eid<=32619760 and type=22 ORDER BY 
> eid DESC LIMIT 1;
> 32619722|22
> CPU Time: user 0.000000 sys 0.000000
>
> sqlite> EXPLAIN QUERY PLAN SELECT events.* FROM events WHERE eid<=32619760 
> and 
> type=22 ORDER BY eid DESC LIMIT 1;
> 0|0|TABLE events USING PRIMARY KEY ORDER BY
>
> ========
> Result: this index is good.
> ========
>
> 2. And I try with two-columns common order index:
> #!/usr/bin/tclsh
> package require sqlite3
> sqlite3 db index_order.db
> db eval {DROP TABLE IF EXISTS events}
> db eval {CREATE TABLE events (eid INTEGER PRIMARY KEY,type INTEGER)}
> db transaction {
>     for {set i 0} {$i<100000000} {incr i} {
>         set type [expr {$i % 50}]
>         db eval {insert into events values ($i,$type)}
>     }
> }
> db eval {CREATE INDEX ev_idx ON events(type,eid)}
> db close
>
> sqlite> SELECT events.* FROM events WHERE eid<=32619760 and type=22 ORDER BY 
> eid DESC LIMIT 1;
> 32619722|22
> CPU Time: user 1.400088 sys 1.696106
>
> sqlite> EXPLAIN QUERY PLAN SELECT events.* FROM events WHERE eid<=32619760 
> and 
> type=22 ORDER BY eid DESC LIMIT 1;
> 0|0|TABLE events WITH INDEX ev_idx ORDER BY
>
> ========
> Result: this index is bad.
> ========
>
> 3. And I try with two-columns desc order index:
> #!/usr/bin/tclsh
> package require sqlite3
> sqlite3 db index_order.db
> db eval {DROP TABLE IF EXISTS events}
> db eval {CREATE TABLE events (eid INTEGER PRIMARY KEY,type INTEGER)}
> db transaction {
>     for {set i 0} {$i<100000000} {incr i} {
>         set type [expr {$i % 50}]
>         db eval {insert into events values ($i,$type)}
>     }
> }
> db eval {CREATE INDEX ev_desc_idx ON events(type asc,eid desc)}
> db close
>
> sqlite> SELECT events.* FROM events WHERE eid<=32619760 and type=22 ORDER BY 
> eid DESC LIMIT 1;
> 32619722|22
> CPU Time: user 0.600037 sys 0.608038
>
> sqlite> EXPLAIN QUERY PLAN SELECT events.* FROM events WHERE eid<=32619760 
> and 
> type=22 ORDER BY eid DESC LIMIT 1;
> 0|0|TABLE events WITH INDEX ev_desc_idx ORDER BY
>
>
> And with modified query:
>
> sqlite> SELECT events.* FROM events WHERE eid>=32619760 and type=22 ORDER BY 
> eid DESC LIMIT 1;
> 99999972|22
> CPU Time: user 0.000000 sys 0.000000
> sqlite> SELECT events.* FROM events WHERE eid<=32619760 and type=22 ORDER BY 
> eid ASC LIMIT 1;
> 22|22
> CPU Time: user 0.000000 sys 0.004000
> sqlite> SELECT events.* FROM events WHERE eid>=32619760 and type=22 ORDER BY 
> eid ASC LIMIT 1;
> 32619772|22
> CPU Time: user 0.284018 sys 0.820051
>
>
>
> ========
> Result: this index is bad.
> ========
>
>
> P.S. Try with primary key index only and write your results.
> _______________________________________________
> 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

Reply via email to