Antti Nietosvaara wrote:
> I have a table T with a few million rows. It has a column C with only
> a handful of distinct values for grouping the data. When a user wants
> to access the data my application reads it from a temporary view:
> CREATE TEMPORARY VIEW T_view AS SELECT * FROM T WHERE (C=1 OR C=2);
> where (C=1 OR C=2) will reflect the permissions of the user.
>
> There is also an index for C:
> CREATE INDEX idx_C ON T(C);

You may find that an index on a column with only a few distinct values 
actually hurts performance. Something as simple as

select * from T where C=1;

may take longer with an index. You see, it takes O(N) time to run this 
query without an index, and O(M (logN)^2) time to run it with index, 
where N is the total number of records in the table, and M is the number 
of records satisfying the condition. So the index has a clear benefit 
when M is much smaller than N, but is obviously detrimental when M is 
close to N. The break-even point occurs approximately at M equal to 10% 
of N.

> I have a problem with performance when using the view for simple
> selects. The following query returns the result immediately:
> SELECT min(C) from T;
>
> However the same query on the view takes a very long time:
> SELECT min(C) from T_view;

Because this query is no longer a simple select. It is translated 
internally into

select min(C) from
(SELECT * FROM T WHERE (C=1 OR C=2));

Index is used to satisfy the WHERE condition - but that's still a 
substantial portion of all records in T, which then have to be scanned 
linearly.

> Is there a way to speed up the queries

Well, if you are talking of this particular query, you can do something 
like this:

select (case when exists (select 1 from T where C=1) then 1
    when exists (select 1 from T where C=2) then 2
    else null end);

This should run fast. However, I kind of doubt that "SELECT min(C) from 
T_view;" is a typical query in your application.

Igor Tandetnik 



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

Reply via email to