Sql 为相等和时间戳范围查询创建索引
我有一个定义如下的表:Sql 为相等和时间戳范围查询创建索引,sql,postgresql,indexing,date-range,Sql,Postgresql,Indexing,Date Range,我有一个定义如下的表: CREATE TABLE sessions ( session_id BIGSERIAL PRIMARY KEY, session_start TIMESTAMP NOT NULL, session_end TIMESTAMP NOT NULL, site_id BIGINT NOT NULL, photo_id BIGINT NOT NULL, uuid TEXT NOT NULL ) CREATE INDEX sess
CREATE TABLE sessions (
session_id BIGSERIAL PRIMARY KEY,
session_start TIMESTAMP NOT NULL,
session_end TIMESTAMP NOT NULL,
site_id BIGINT NOT NULL,
photo_id BIGINT NOT NULL,
uuid TEXT NOT NULL
)
CREATE INDEX sessions_lookup ON sessions (
site_id, photo_id, uuid, session_start, session_end
)
我需要对它运行这种类型的查询:
SELECT session_id
FROM sessions
WHERE site_id = %s
AND photo_id = %s
AND uuid = %s
AND %s <@ tsrange(
session_start - interval '3 hours',
session_end + interval '3 hours'
)
后续运行将提供~0.080ms的查询运行时
理想情况下,我希望使用索引作为时间戳查找的一部分,但它似乎被完全忽略(在索引中使用或不使用它的结果相同)。我是否需要更改字段的顺序,或者我是否做错了什么(我是否需要不同类型的索引)
这是在一个有45k条记录的表上进行测试的,但如果需要,我可以创建一个更大的样本集。第一个想法:工作就像重叠(
&&
)。包含(我不认为我做了一些测试并得出了相同的结论-我基本上必须使用原始列值并操作给定的时间戳,以适应良好的性能(这不是问题,只是必须在客户端而不是在SQL中执行)。作为一个额外的好处,我可以将会话\u id添加到仅索引扫描的末尾,尽管包含了很多字段,但仍然只有表大小的1/7。这一切都很重要:)
Index Scan using sessions_lookup on sessions (cost=0.00..8.30 rows=1 width=8) (actual time=0.062..0.063 rows=1 loops=1)
Index Cond: ((site_id = 10113150) AND (photo_id = 10240980) AND (uuid = '042d6f26-e298-0140-a4cc-7bfd0f9ccd27'::text))
Filter: (((session_start - '03:00:00'::interval) <= '2014-09-05 09:45:38'::timestamp without time zone) AND ((session_end + '03:00:00'::interval) >= '2014-09-05 09:45:38'::timestamp without time zone))
Total runtime: 1.384 ms
(4 rows)
(session_start - interval '3 hours' <= '2014-09-05 09:45:38') AND
(session_end + interval '3 hours' >= '2014-09-05 09:45:38')
(session_start <= '2014-09-05 09:45:38'::timestamp + interval '3 hours') AND
(session_end >= '2014-09-05 09:45:38'::timestamp - interval '3 hours')
SELECT session_id
FROM sessions
WHERE site_id = %s
AND photo_id = %s
AND uuid = %s
AND (session_start <= %s::timestamp + interval '3 hours')
AND (session_end >= %s::timestamp - interval '3 hours')