Hi List,

I was looking at the query plan of a rather simple query, but I don't 
understand why sqlite would choose this query plan.

For the following example:

create table aaa(id INTEGER, name_id INTEGER, type CHAR);
create table bbb(name_id INTEGER, name CHAR);
create index ix_aaa ON aaa(id);
create index ix_bbb ON bbb(name_id);

.explain ON

explain query plan 
SELECT aaa1.name_id,
       bbb1.name
  FROM aaa aaa1,
       aaa aaa2 ON aaa1.id   = aaa2.id,
       bbb bbb1 ON bbb1.name_id = aaa1.name_id
WHERE aaa1.type =  'A'
  AND aaa2.type <> 'A';


=========== output ==============

SELECT item[0] = {0:1}
       item[1] = {2:1}
FROM {0,*} = aaa (AS aaa1)
     {1,*} = aaa (AS aaa2)
     {2,*} = bbb (AS bbb1)
WHERE AND(AND(AND(EQ({0:2},'A'),NE({1:2},'A')),EQ({0:0},{1:0})),EQ({2:0},{0:1}))
END
sele  order          from  deta
----  -------------  ----  ----
0     0              0     SEARCH TABLE aaa AS aaa1 USING AUTOMATIC COVERING 
INDEX (type=?)
0     1              1     SEARCH TABLE aaa AS aaa2 USING INDEX ix_aaa (id=?)
0     2              2     SEARCH TABLE bbb AS bbb1 USING INDEX ix_bbb 
(name_id=?)

Sqlite decides to create an AUTOMATIC INDEX (time complexity O(n log n)) which 
it then uses to iterate table aaa1. This index is not re-used for anything else 
(it can't be re-used since 'type' is not used anywhere else) so only the 
traversal of table aaa1 benefits from this index. However, I think, a full 
table scan of aaa1 (time complexity O(n)) would always be faster, since for 
creating the index it has to read that entire table anyway.

I was surprised that sqlite came up with the inferior query plan.
What makes sqlite think that creating + using an automatic index (for the outer 
loop) makes the query faster the a full scan + filtering records? Is the 
estimation of the costs for some action very bad for this query? Can I somehow 
show the costs of a query plans (or of the rejected query plans)?

I'm using sqlite version 3.8.4.3

Note: After an "analyze aaa" (on a decently populated table) sqlite chooses the 
full table scan instead of creating an automatic index (but our application 
never uses 'analyze' to avoid that other (bad performing) query plans are used 
during operation than during testing).
Note 2: Adding "NOT INDEXED" to aa1 gives the desired query plan, but of course 
I prefer that sqlite choses the right query plan.

Regards,
Rob Golsteijn

 
 
_______________________________________________
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to