我正在设计一些系统来存储包含开始和结束时间的记录。例如:PostgreSQL匹配时间戳的开始时间和结束时间间隔
CREATE TABLE test (
id bigserial PRIMARY KEY,
ts_start timestamp NOT NULL,
ts_end timestamp NOT NULL,
foo bar NOT NULL,
...
);
现在我想对此运行查询以查找与某个时间戳重叠的所有行。这将导致一个where子句,如:
WHERE ts_start <= '2006-4-6 12:34:56' AND ts_end > '2006-4-6 12:34:56'
我用大量生成的测试数据对此进行了测试,性能非常糟糕。我使用ts_start上的索引和ts_end上的另一个索引以及ts_start和ts_end上的多列索引对其进行了测试。最后一次给出了最好的结果,但它仍然远未达到最佳状态。
问题是,postgresql不知道ts_end保证大于ts_start的事实,所以它使用一个能够查找ts_end小于ts_start的行的计划。
有什么建议如何解决这个问题?
编辑: 对于有这个问题的人们,如果您可以等待一段时间,那么PostgreSQL 9.2有完美的解决方案:range types。 9.2在测试版现在最终版本将最有可能在2012年
我刚建立了一个简单的测试表,开始和结束时间戳,都是随机的,所有结束>开始的随机数,并在我的笔记本电脑表中有1M行我得到的结果为计数(*)其中范围在30至300ms范围内高于上述范围。改变random_page_cost(降低它)有利于索引,并且获得更好的运行时间。这张桌子有多大? – 2011-05-14 10:35:07
@Scott:目前我正在测试1900万行,并且它需要大约6秒(和高cpu负载)以及多列索引。我有另一个类似的用例,其中有一个额外的限制,允许针对类似大小的表和结果只需要一毫秒的更具针对性的查询。 – Eelke 2011-05-14 11:21:29
你的解释分析对查询计划有什么看法?降低random_page_cost直到使用索引扫描有帮助吗? – 2011-05-14 20:51:02