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