Thread: indexes using datetime

indexes using datetime

From
Michael Richards
Date:
Hi.
I've got a slow query I can't seem to fix...
Table    = logins
+-------------------------+----------------------------------+-------+
|           Field         |              Type                | Length|
+-------------------------+----------------------------------+-------+
| loginid                 | varchar()                        |    16 |
| logintime               | datetime                         |     8 |
| ip                      | varchar()                        |    15 |
| direction               | char()                           |     1 |
+-------------------------+----------------------------------+-------+
Indices:  logins_direction_idx         logins_logintime_idx

So I've got this table that records stuff about people logging in. Since
it's essentially a log, it is very large. About 1.3 million tuples.

I've created an index on the logintime with hopes I can make some of my
queries which care only about the last 40 day's of logins use the query
and ignore the rest of the tuples...

explain select * from logins where logintime>'now'::datetime-'40
days'::timespan;
NOTICE:  QUERY PLAN:

Seq Scan on logins  (cost=5839.78 rows=44958 width=44)

Very bad query plan :(

As I recall, you should be able to make a btree traversal return all its
values in order. So then isn't it reasonable that the dbms should be using
the index to find all the values within a certain range?

-Michael



Re: [SQL] indexes using datetime

From
Tom Lane
Date:
Michael Richards <miker@scifair.acadiau.ca> writes:
> explain select * from logins where logintime>'now'::datetime-'40
> days'::timespan;
> NOTICE:  QUERY PLAN:
> Seq Scan on logins  (cost=5839.78 rows=44958 width=44)

> Very bad query plan :(

Yah.  It's got nothing to do with datetime though.  Problem is that the
system can only make indexscans work with WHERE clauses of the form
"field op constant" (for "op"s related to the sort ordering of the
index of course).  Your righthand side is not a constant.

Eventually, maybe for 6.6 or 6.7, we will have the smarts in place to
reduce constant expressions to simple constants during preprocessing of
a query.  For now, you are going to have to structure your application to
precompute the value that's going to be compared against index entries.
        regards, tom lane


Re: [SQL] indexes using datetime

From
Herouth Maoz
Date:
At 03:46 +0300 on 29/08/1999, Tom Lane wrote:


> Michael Richards <miker@scifair.acadiau.ca> writes:
> > explain select * from logins where logintime>'now'::datetime-'40
> > days'::timespan;
> > NOTICE:  QUERY PLAN:
> > Seq Scan on logins  (cost=5839.78 rows=44958 width=44)
>
> > Very bad query plan :(
>
> Yah.  It's got nothing to do with datetime though.  Problem is that the
> system can only make indexscans work with WHERE clauses of the form
> "field op constant" (for "op"s related to the sort ordering of the
> index of course).  Your righthand side is not a constant.

A tip: use

SELECT 'now'::datetime - '40 days'::timespan;

Get the result on your client side, say in a variable named $x, and use it
in the "real" query:

SELECT * FROM logins WHERE logintime > $x;

(Actual embedding protocol depends, of course, on the language you use).

Then it's a constant, as far as Postgres is concerned, and the time wasted
for the small query is really not an issue.

Herouth

--
Herouth Maoz, Internet developer.
Open University of Israel - Telem project
http://telem.openu.ac.il/~herutma