"Any Index that starts with a Unique column will by definition be Unique."
Sorry, yet, I admit the title of the thread is confusing. What I meant to say 
is that it's TOO unique :). Adding the additional columns will allow duplicates 
on the columns where duplicates should not be allowed.


"This Query (for instance) will be exceedingly fast:
SELECT ExtraCol FROM Foo WHERE UniqueCol > range_start AND UniqueCol < 
range_end"

No, that's not covered. I've tried that before, that query is too slow when it 
isn't covered - the table is many GB's and the result is needed in low 
milliseconds. Also, I don't need an index directly on ExtraCol like specified 
below for the ( WHERE ExtraCol = ...) case . It's not useful a useful lookup by 
itself - only a useful result. So the only reason to include it in an index is 
to make it covered.


"You cannot optimize for everything, pick your favourite thing and optimize for 
that."

This is a bit of a call to support INCLUDE columns in indexes. This 
optimization is very easy in SQL Server using that.

- Deon

-----Original Message-----
From: sqlite-users [mailto:sqlite-users-boun...@mailinglists.sqlite.org] On 
Behalf Of R Smith
Sent: Thursday, March 2, 2017 2:50 AM
To: sqlite-users@mailinglists.sqlite.org
Subject: Re: [sqlite] Non-unique columns in unique index

Any Index that starts with a Unique column will by definition be Unique. 
Of course in your case you want the Uniqueness of only the first column to be 
enforced, but you want to lookup also using the second column (either or both). 
Why insist on having it in a covering Index though?

Why not just make one Unique index, and one other Index on the other column by 
itself? Like so:

+CREATE TABLE Blah(
     Id Integer Primary Key,
     UniqueCol blob, // 20 bytes fixed
     ExtraCol blob, // 12 bytes fixed
     UNIQUE(UniqueCol)
);  // ~36 bytes/row

CREATE INDEX Blah_ExtraIdx on Blah(ExtraCol);


This will be close to the same size of one covering Index.
The Query planner is clever enough to figure out it can use only the second 
Index to look up some queries, it can also use the Unique Index if needed for a 
query and it will use it to enforce uniqueness.

You get all the speed and a little extra overhead space, but much less than a 
covering Index.

This Query (for instance) will be exceedingly fast:
SELECT ExtraCol FROM Foo WHERE UniqueCol > range_start AND UniqueCol < range_end

So would this:
SELECT * FROM Foo WHERE UniqueCol > range_start AND UniqueCol < range_end AND 
ExtraCol = xxx;

And this:
SELECT * FROM Foo WHERE ExtraCol = xxx;

All of these will be super fast and your Indices will take up the least 
possible space.

There is some saving in cycles if you can read the bytes directly out of a 
covering Index rather than a big table, but this is no big table, it should be 
real quick. If you really really really need those few cycles saved, invest the 
MBs and make the covering Index additional. If space is a problem, use only the 
single Unique index.

You cannot optimize for everything, pick your favourite thing and optimize for 
that.

Cheers,
Ryan

On 2017/03/01 7:00 PM, Deon Brewis wrote:
> Is there way to add non-unique columns in a unique index?
>
> I would like to use the same index to enforce unique constraints, as well as 
> giving a covered result for other queries.
>
> Something like an 'INCLUDE' would also work (actually even better). E.g.
>
> CREATE UNIQUE INDEX indx  ON Foo(UniqueCol) INCLUDE (ExtraCol)
>
>
> If not, is there a way to efficiently implement a UNIQUE constraint in 
> a different way? (Trigger maybe?)
>
> -Deon
>   
> _______________________________________________
> sqlite-users mailing list
> sqlite-users@mailinglists.sqlite.org
> http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users

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

Reply via email to