日期时间范围的Postgresql最佳索引

日期时间范围的Postgresql最佳索引,postgresql,indexing,Postgresql,Indexing,我有一个Postgre表“tasks”,其中包含字段“start”:timestamtz,“finish”:timestamtz,“type”:int(以及许多其他字段)。它包含大约2亿条记录。“开始”、“完成”和“类型”字段有单独的b树索引。 我想建立一个报告“一段时间内的任务”,并需要获取报告期内(全部或部分)的所有任务。可以为所有任务类型或特定任务类型生成报告。 所以我写了SQL: SELECT * FROM tasks WHERE start<={report_to} AND

我有一个Postgre表“tasks”,其中包含字段“start”:timestamtz,“finish”:timestamtz,“type”:int(以及许多其他字段)。它包含大约2亿条记录。“开始”、“完成”和“类型”字段有单独的b树索引。 我想建立一个报告“一段时间内的任务”,并需要获取报告期内(全部或部分)的所有任务。可以为所有任务类型或特定任务类型生成报告。 所以我写了SQL:

SELECT * FROM tasks 
WHERE start<={report_to} 
AND finish>={report_from}
AND ({report_tasktype} IS NULL OR type={report_tasktype})
从任务中选择*
其中start={report_from}
和({report\u tasktype}为NULL或type={report\u tasktype})
即使报告期很短,它也会运行很长时间。
请告知是否有办法通过更改查询或在表上创建新索引来提高性能?由于某些原因,我无法更改“任务”表的结构

您可能需要范围的要点索引。因为您已经将其存储为两个端点而不是一个范围,所以您可以执行函数索引来动态转换它们

ON task USING GIST (tstzrange(start,finish))
然后将重叠范围与
&


在索引中添加“type”作为第二列也可能会有所改进,这将需要btree_gist扩展。

您可能希望在范围中添加gist索引。因为您已经将其存储为两个端点而不是一个范围,所以您可以执行函数索引来动态转换它们

ON task USING GIST (tstzrange(start,finish))
然后将重叠范围与
&


在索引中添加“type”作为第二列也可能会有所改进,这需要使用btree\u gist扩展。

根据报告参数,使用
explain
@bigbounty了解您的查询。当提供report_tasktype时,它在“type”上使用索引扫描,在“start”和“finish”子句上使用过滤器。当报告期与上月相同时,它在“完成”时使用索引扫描,在“开始”时使用过滤器。否则,它将使用SeqScan根据报告参数使用
explain
@bigbounty来理解您的查询。当提供report_tasktype时,它在“type”上使用索引扫描,在“start”和“finish”子句上使用过滤器。当报告期与上月相同时,它在“完成”时使用索引扫描,在“开始”时使用过滤器。否则,它会被使用。谢谢!GIST关键字将我带到这里(是的,我承诺在提问之前使用搜索)谢谢!GIST关键字将我带到这里(是的,我承诺在提问之前使用搜索)