Thread: RE: [SQL] indexing a datetime by date

RE: [SQL] indexing a datetime by date

From
"Jackson, DeJuan"
Date:
Part of the problem is that PostgreSQL Assumes that a functions value will
change each time it is required, therefore automatic table scan and the
function is called for each row.
Try using 'now'::date instead of now()::date
You index creation syntax is good but there's a bug in function indexes
which require you to specify the ops. Try:create index when_ndx3 on notes (date(when) date_ops);

Which won't work because the date(datetime) function isn't trusted.
You can change this yourself in the system tables or you can use PL/PGSQL
(the only trustable PL in PostgreSQL that I've found) to create another
conversion function and use it instead.  Or you can as Thomas Lockhart (or
is it Tom Lane) if he'd create a trusted function for the conversions in
6.5.
DISCLAIMER: I haven't tested this on the current CSV(?CVS I just can't think
tonight) so it might already be fixed.-DEJ

> -----Original Message-----
> From: Andrew Merrill [mailto:andrew@compclass.com]
> Sent: Monday, March 29, 1999 9:28 PM
> To: pgsql-sql@hub.org
> Subject: [SQL] indexing a datetime by date
> 
> 
> I have a table with a field, "when", of type "datetime".  I can't use
> "date" because I need the times as well.  I'm using PostgreSQL 6.4.2.
> 
> I'd like to identify all of the records with today's date, as in:
> 
> select when from notes where when::date = now()::date;
> 
> The query works, but is very slow.  Explain confirms that a sequential
> scan is being used.
> 
> I've tried indexing on when:
> 
> create index when_ndx1 on notes (when);
> 
> But that doesn't help, as (I suppose) the optimizer can't match
> when::date with this index.
> 
> Neither of these works:
> 
> db=> create index when_ndx2 on notes (when::date);
> ERROR:  parser: parse error at or near "::"
> 
> db=> create index when_ndx3 on notes (date(when));
> ERROR:  DefineIndex:  class not found
> 
> As a workaround, I've been using this:
> 
> select when from notes where when >= '3/29/1999 0:0:0' and when <=
> '3/29/1999 23:59:59';
> 
> but that's ugly and requires hardcoding today's date each time, rather
> than using now().
> 
> So, the question is, is there a way to index a datetime field by date?
> 
> Andrew Merrill
> 
> 


Re: [SQL] indexing a datetime by date

From
Thomas Lockhart
Date:
> Your index creation syntax is good but there's a bug in function 
> indexes which require you to specify the ops. Try:
>  create index when_ndx3 on notes (date(when) date_ops);
> Which won't work because the date(datetime) function isn't trusted.
> You can change this yourself in the system tables or you can use 
> PL/PGSQL (the only trustable PL in PostgreSQL that I've found) to 
> create another conversion function and use it instead.  Or you can as 
> Thomas Lockhart (or is it Tom Lane) if he'd create a trusted function 
> for the conversions in 6.5.

Tom, does this ring a bell with you? istm that (almost) all builtin
functions should be trusted, but I haven't done anything explicit
about it that I can remember.

In your new role as System Table Berserker, perhaps you would want to
fix this? :)
                      - Tom


RE: [SQL] indexing a datetime by date

From
Herouth Maoz
Date:
At 06:07 +0200 on 30/03/1999, Jackson, DeJuan wrote:


>
> Part of the problem is that PostgreSQL Assumes that a functions value will
> change each time it is required, therefore automatic table scan and the
> function is called for each row.
> Try using 'now'::date instead of now()::date

How about using the ANSI standard CURRENT_DATE instead of either? It's
already of type date. Or is it considered a function call?

Herouth

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




Re: [SQL] indexing a datetime by date

From
Tom Lane
Date:
Thomas Lockhart <lockhart@alumni.caltech.edu> writes:
>> create index when_ndx3 on notes (date(when) date_ops);
>> Which won't work because the date(datetime) function isn't trusted.

> Tom, does this ring a bell with you?

No, and in fact datetime_date *is* marked trusted in pg_proc,
both current sources and 6.4.2.

I see the problem DeJuan is getting at:

play=> create table notes (when datetime);
CREATE
play=> create index when_ndx3 on notes (date(when) date_ops);
CREATE
play=> insert into notes values ('now');
ERROR:  internal error: untrusted function not supported.

This is either a bug or a very poorly worded error message.
I'll look into it.

In the meantime, a workaround is to call the function using its
builtin name:

play=> create table notes (when datetime);
CREATE
play=> create index when_ndx3 on notes (datetime_date(when) date_ops);
CREATE
play=> insert into notes values ('now');
INSERT 1086489 1

In 6.4.2, date() on a datetime is an SQL-language function that just
calls the builtin function datetime_date().  It would seem that 6.4.2
can't cope with an SQL-language function as an index generator.  This
might be a minor bug or it might be difficult to change; I dunno.

In 6.5, date() on a datetime is a true builtin, on par with
datetime_date(), so you'll be able to use either name interchangeably in
that release.  But we may still not be able to do anything with other
SQL-language functions as index generators.
        regards, tom lane


Re: [SQL] indexing a datetime by date

From
Andrew Merrill
Date:
Tom Lane wrote:

> In the meantime, a workaround is to call the function using its
> builtin name:
>
> play=> create table notes (when datetime);
> CREATE
> play=> create index when_ndx3 on notes (datetime_date(when) date_ops);
> CREATE

Thanks, that helps - I can now index a datetime field by date.But the index
doesn't appear to be used:

db=> create index ndx3 on notes (datetime_date(when) date_ops);
CREATE
db=> vacuum analyze notes;
VACUUM
db=> explain select when from notes where when::date = 'now'::date;
NOTICE:  QUERY PLAN:

Seq Scan on notes  (cost=4330.37 size=43839 width=8)

EXPLAIN

So it appears that the optimizer doesn't like this index.  (This is with
version 6.4.2.)
The table has about 90,000 rows, of which between 10 and 100 might match a
given date, so an index would really help.

Am I missing something simple here?  Thanks again for all your help.

Andrew Merrill