优化在日期搜索的常用查询

时间:2016-05-03 01:38:32

标签: sql postgresql

我有一个使用postgres的Web应用程序(Rails),它有表openings

openings表有一些属性,与此查询相关的属性是valid_till - datetime和'is_downloaded' - 布尔值。

现在几乎每个页面请求我都要检查是否有任何 - 有效的未下载开口。

如果valid_till小于或等于current_timeis_downloaded为假,则开放有效并且未下载。

SELECT  "openings".*  
FROM "openings" 
WHERE (valid_till >= CURRENT_TIMESTAMP and is_downloaded IS false) 
LIMIT 1

我构建了一个sql查询我只想尽可能地优化它,因为它几乎会在每个页面请求中使用。随着时间的推移,openings表将获得大量记录。

2 个答案:

答案 0 :(得分:3)

你想要一个索引。我建议:

create index idx_openings_isdownloaded_validtill on openings(is_downloaded, valid_till)

但是,我要提醒的是,在没有limit的情况下使用order by通常是一个坏主意。如果没有order by,它将返回一个不确定的匹配行。

编辑:

Jmelesky建议,过滤/部分索引可能更适合此查询:

create index idx_openings_isdownloaded_validtill
    on openings(valid_till)
    where not is_downloaded;

答案 1 :(得分:1)

  

现在几乎每个页面请求我都要检查是否有任何 - 有效的未下载开口。

然后使用EXISTS

更合适
SELECT CASE WHEN EXISTS(SELECT  NULL FROM "openings" 
                        WHERE valid_till >= CURRENT_TIMESTAMP
                              and is_downloaded IS false)
       THEN 1
       ELSE 0 END

EXISTS的好处是编译器可以优化掉与匹配记录是否存在无关的任何计算。您也没有通过选择*返回任何不必要的数据 - 您只是通过线路传输一个标量值。

提高此特定查询性能的最佳方法是在(valid_till, is_downloaded)上设置复合索引。