Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Postgresql Query very slow with ::date, ::time, and interval

Tags:

postgresql

I have a sql query that is very slow:

        select number1 from mytable
        where symbol = 25
        and timeframe = 1
        and date::date = '2008-02-05'
        and date::time='10:40:00' + INTERVAL '30 minutes'

The goal is to return one value, and postgresql takes 1.7 seconds to return the desired value(always a single value). I need to execute hundreds of those queries for one task, so this gets extremely slow. Executing the same query, but pointing to the time directly without using interval and ::date, ::time takes only 17ms:

    select number1 from mytable
    where symbol = 25
    and timeframe = 1
    and date = '2008-02-05 11:10:00'

I thought it would be faster if I would not use ::date and ::time, but when I execute a query like:

    select number1 from mytable
    where symbol = 25
    and timeframe = 1
    and date = '2008-02-05 10:40:00' + interval '30 minutes'

I get a sql error (22007). I've experimented with different variations but I couldn't get interval to work without using ::date and ::time. Date/Time Functions on postgresql.org didn't help me out.

The table got a multi column index on symbol, timeframe, date.

Is there a fast way to execute the query with adding time, or a working syntax with interval where I do not have to use ::date and ::time? Or do I need to have a special index when using queries like these?

Postgresql version is 9.2.

Edit: The format of the table is: date = timestamp with time zone, symbol, timeframe = numeric.

Edit 2: Using

select open from ohlc_dukascopy_bid
where symbol = 25
and timeframe = 1
and date = timestamp '2008-02-05 10:40:00' + interval '30' minute

Explain shows:

"Index Scan using mcbidindex on mytable  (cost=0.00..116.03 rows=1 width=7)"
"  Index Cond: ((symbol = 25) AND (timeframe = 1) AND (date = '2008-02-05 11:10:00'::timestamp without time zone))"

Time is now considerably faster: 86ms on first run.

like image 568
harbun Avatar asked Oct 22 '25 04:10

harbun


1 Answers

The first version will not use a (regular) index on the column named date.

You didn't provide much information, but assuming the column named date has the datatype timestamp (and not date), then the following should work:

and date = timestamp '2008-02-05 10:40:00' + interval '30 minutes'

this should use an index on the column named date (but only if it is in fact a timestamp not a date). It is essentially the same as yours, the only difference is the explicit timestamp literal (although Postgres should understand '2008-02-05 10:40:00' as a timestamp literal as well).

You will need to run an explain to find out if it's using an index.

And please: change the name of that column. It's bad practise to use a reserved word as an identifier, and it's a really horrible name, which doesn't say anything about what kind of information is stored in the column. Is it the "start date", the "end date", the "due date", ...?