Postgresql在动态值上创建函数索引

时间:2018-05-01 13:27:31

标签: postgresql indexing

我有这样的查询

select r.timestamp, r,value
   from result_table r
  where timestamp > ( NOW() - INTERVAL '120 hour' )
    and r.id%10=1`

其中id是自动增量主键。

相反,120和10可以是任何其他数字(由用户根据他的需要决定)。基本上,用户需要一些时间间隔的数据并进行一些抽取。

显然,它对大量数据的运行速度太慢。这里的指数应该是什么?

1 个答案:

答案 0 :(得分:0)

PostgreSQL支持SQL表达式或函数索引

  where
    timestamp > ( NOW() - INTERVAL '120 hour' )
    and r.id % 10 = 1

需要索引(timestamp, (id % 10))才能获得更高的效果。

<强>查询

CREATE INDEX
 timestamp__idmod10
ON 
 result_table
(timestamp, (id % 10))

参见演示

索引http://sqlfiddle.com/#!17/8e63b/6
没有索引http://sqlfiddle.com/#!17/9be99/3

因评论而编辑

  

谢谢,Raymond,然而,(id%10)并不是那么好,而不是   10可以是任何其他数字。 9,11,100,1等

其他方法使用generate_series()和传递的表格来生成匹配%number = 1的id列表 并将该结果集与IN子句一起使用。

p.s此语句假设一个带有SERIAL的id列和一个等于或小于100万条记录的表。另请注意,generate_series()函数需要一些时间。

SQL语句

 SELECT 
   numbers.number FROM (  
      SELECT
        generate_series(1, 1000000) as number
      ) AS numbers 
    WHERE
      numbers.number % number = 1

然后你可以使用索引

CREATE INDEX timestamp_id ON result_table(timestamp, id);

和查询

SELECT 
 *
FROM 
 result_table 
WHERE
   timestamp > ( NOW() - INTERVAL '120 hour' ) 
 AND
   id IN (

     SELECT 
       numbers.number FROM (  
          SELECT
            generate_series(1, 1000000) as number
          ) AS numbers 
        WHERE
          numbers.number % 10 = 1

   )

使用示例数据查看演示http://sqlfiddle.com/#!17/5013c0/6