3

我有一个非常慢的 sql 查询:

        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'

目标是返回一个值,postgresql 需要 1.7 秒才能返回所需的值(总是一个值)。我需要为一项任务执行数百个这样的查询,所以这变得非常慢。执行相同的查询,但不使用interval和::date直接指向时间,::time只需要17ms:

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

我认为如果我不使用 ::date 和 ::time 会更快,但是当我执行如下查询时:

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

我收到一个 sql 错误 (22007)。我已经尝试了不同的变体,但如果不使用 ::date 和 ::time,我无法获得工作间隔。postgresql.org 上的日期/时间函数并没有帮助我。

该表有一个关于交易品种、时间范围、日期的多列索引。

有没有一种通过添加时间来执行查询的快速方法,或者有一个工作语法与我不必使用 ::date 和 ::time 的间隔?或者在使用这样的查询时我是否需要有一个特殊的索引?

Postgresql 版本是 9.2。

编辑:表格的格式是:日期=带有时区的时间戳,符号,时间范围=数字。

编辑 2:使用

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

解释显示:

“在 mytable 上使用 mcbidindex 进行索引扫描(成本=0.00..116.03 行=1 宽度=7)”
" Index Cond: ((symbol = 25) AND (timeframe = 1) AND (date = '2008-02-05 11:10:00'::timestamp without time zone))"

时间现在大大加快:第一次运行 86 毫秒。

4

1 回答 1

6

第一个版本不会在名为 的列上使用(常规)索引date

您没有提供太多信息,但假设名为的列date具有数据类型 timestamp(而不是date),那么以下应该可以工作:

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

这应该在名为的列上使用索引date(但前提是它实际上是 atimestamp而不是 a date)。它与您的基本相同,唯一的区别是显式时间戳文字(尽管 Postgres也应该理解'2008-02-05 10:40:00'为时间戳文字)。

您需要运行 anexplain来确定它是否使用索引。

请:更改该列的名称。使用保留字作为标识符是一种不好的做法,而且它是一个非常可怕的名称,它并没有说明该列中存储了什么样的信息。是“开始日期”、“结束日期”、“截止日期”……?

于 2013-01-03T09:41:43.827 回答