On 2019/04/30 2:10 AM, Deon Brewis wrote:
Given the SQL below, FooX is a covered index for x on Foo.
I want to create FooXB as a second index on x in Foo. Since 'x' is covered on
FooX it should be cheaper to build FooXB from index FooX, than from table Foo.
However, as far as I can tell from the from the opcodes of the index creation
it doesn't do this (OpenRead uses rootpage=2 instead of 3). Is my understanding
correct?
Not quite. This is a good example of something that "feels" like it
should be better, just isn't.
Unless Foo(x) is a partial Index and the new index can somehow indicate
that it has the same partiality as the original index (which it can't
unless it's exactly equal, in which case, it's useless), there can be no
advantage.
Keep in mind that, in SQLite, a table is nothing less than a covering
Index itself with the row_id as the indexer (or the actual PK in the
case of WITHOUT ROWID tables). There is no reason why it itself (being
an Index) should be any slower to "walk" than any other Index, in fact a
lookup via any other index will include an extra step (the lookup
itself) that you don't have when walking the table index itself (aka
doing a "table scan"). It's just better for anything where you access
any field that are not in the existing index, and not worse for those
that are.
There might be a small but real advantage if the field (that was indexed
on) appeared at the end of very long list of fields or very large
fields, i.e. hidden at the back end of the column list with really large
(long-to-read) columns preceding it - meaning the existing Index would
already have singled out that bit of data - but it's a very small
likelihood and use-case though. (Meaning that it's unlikely for people
to make multiple Indexes on the same field(s), so investing the effort
and code-bloat in catering for the optimization it, which would only
ever benefit it in the case where the column IS at the back of big other
columns, would be of dubious benefit).
And if my understanding is correct, is there any scenarios in which I can
coerce SQLITE to build a new index based on data in an existing index?
drop table Foo;
create table Foo(x text, y text, z text);
insert into Foo(x) values("elephant");
insert into Foo(x) values("cat");
insert into Foo(x) values("giraffe");
insert into Foo(x) values("dog");
insert into Foo(x) values("zebra");
insert into Foo(x) values("lion");
insert into Foo(x) values("panther");
create index FooX on Foo(x);
create index FooXB on Foo(substr(x,2,1)) where substr(x,2,1) > 'e';
As an aside - if your INSERTs above was a "find the odd one out" puzzle,
I vote that the answer would be "panther". :)
Cheers,
Ryan
_______________________________________________
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users