Klaus Schären wrote:

Hi

i have the following table definition:
CREATE TABLE Pistor (Nummer INTEGER PRIMARY KEY NOT NULL, Artikel TEXT NOT
NULL DEFAULT '', Inhalt TEXT NOT NULL DEFAULT '')

In addition, I have created  the following index:
CREATE UNIQUE INDEX xPistor ON PISTOR(ARTIKEL, NUMMER)

when i run a query with "order by artikel", sqlite returns the result very
fast.
Query: SELECT ARTIKEL, NUMMER FROM PISTOR ORDER BY ARTIKEL

when i run a quey with "order by artikel, nummer" (witch is exactly the
index xPistor!), sqlite takes longer.
Query: SELECT ARTIKEL, NUMMER FROM PISTOR ORDER BY ARTIKEL, NUMMER

i run the explain command with both querys. with the second query, sqlite
makes a sort. is this ok? why does sqlite not use the index xPistor?

i try the query with different versions of sqlite (3.2.8, 3.3.1 and 3.3.2).
I have also running the ANALYZE command. but nothing is changing.

the test db is included in the attached zip.

thanks for your help

K. Schären

Klaus,

You have defined the field Nummer as a primary key. Therefore, each row will have a unique value of Nummer. Your second index will enforce a rule that all pairs of Artikel and Nummer must be unique, but that must always be true since all values of Nummer are unique, regardless of the value of Artikel.

The fact that Nummer is a primary key seems to confuse the optimizer for this query. If I remove the primary key part of the definition from the field Nummer, and use the explicit unique index you defined, then the second query uses that index. When I do this:

CREATE TABLE Pistor2 (Nummer INTEGER NOT NULL, Artikel TEXT NOT
NULL DEFAULT '', Inhalt TEXT NOT NULL DEFAULT '')

CREATE UNIQUE INDEX xPistor2 ON PISTOR2(ARTIKEL, NUMMER)

insert into pistor2 select * from pistor

explain query plan SELECT ARTIKEL, NUMMER FROM PISTOR ORDER BY ARTIKEL, NUMMER

the query plan shows that the index is being used, and an explain command shows that the sort is not done.

I think you have found an issue (I won't call it a bug because the query does work correctly) with the optimizer. Your first query uses the index because the output list is not ordered by Nummer, so the implicit index on Nummer is not of any use, and the optimizer then find the other index and uses it. The second query seems to think that it can use the implicit index on Nummer to do part of the ordering, and since SQLite only uses one index per table scan it can't use the explicit index. Then it determines that it needs to do a sort to order by Artikel. My change removes the implicit index on Nummer, so then it finds and uses the explicit index to scan the table in the correct order.

HTH
Dennis Cote

Reply via email to