Ann*_*nna 4 postgresql performance gist-index range-types postgresql-performance
我有一个包含日期时间字段start
和end
. 我有一个(开始,结束)项目列表。我需要检查列表中的哪些项目与表中的数据重叠。当前查询如下所示:
select br.duration from booking, (
select tstzrange('2016-09-06 03:45:00+00', '2016-09-06 14:45:00+00') as duration
union select tstzrange('2016-09-06 14:45:00+00', '2016-09-06 15:45:00+00') as duration
-- other items from my list
) as br
where tstzrange(start, end) && br.duration
Run Code Online (Sandbox Code Playgroud)
有没有其他方法可以做到?如果我在表中有数百万行并将它们与列表中的数百个项目进行比较,您认为它会起作用吗?
我建议对处理一百万行进行一些重要的改进:
SELECT br.duration
FROM (
VALUES
('[2016-09-06 03:45:00+00, 2016-09-06 14:45:00+00)'::tstzrange)
, ('[2016-09-06 14:45:00+00, 2016-09-06 15:45:00+00)')
-- more items
) br(duration)
WHERE EXISTS (
SELECT FROM booking
WHERE tstzrange(ts_start, ts_end) && br.duration
);
Run Code Online (Sandbox Code Playgroud)
在以不必要的冗长和昂贵的形式提供您的值列表时SELECT ... UNION ...
,请使用它UNION ALL
,否则 Postgres 将浪费时间尝试折叠重复项。而你只需要声明的列名(S)和第一数据类型SELECT
的的UNION
查询。
但是VALUES
表达式更简单、更快。或者提供一个数组tstzrange[]
并使用unnest()
:
您拥有的查询将为 中的每个重叠行返回一行booking
,而您很可能希望列表中的每个重叠值一次。您可以添加DISTINCT
或GROUP BY
获取唯一的行,但这仍然会浪费时间。一个EXISTS
半连接是你的情况下,更简单,更便宜的替代品之一:每行从duration
如果重复条目中发现和Postgres可以停止进一步寻找此行返回一次。
如果没有索引支持,查询仍然会很慢。创建功能性 GiST 或SP-GiST 索引。后者可能表现最好:
CREATE INDEX booking_ts_range_idx on booking USING spgist (tstzrange(ts_start, ts_end));
Run Code Online (Sandbox Code Playgroud)有关的:
归档时间: |
|
查看次数: |
2635 次 |
最近记录: |