我的表格包含first_seen
(日期时间),last_seen
(日期时间)和severity
(整数)的事件。
我试图在谨慎的15分钟间隔内找到有多少活动:
WITH intervals AS
(
SELECT
'2016-08-02 00:00:00'::TIMESTAMP
+ (n||' minutes')::INTERVAL AS start_time,
'2016-08-02 00:00:00'::TIMESTAMP
+ ((n + 15)||' minutes')::INTERVAL AS end_time
FROM generate_series(0, 24 * 60, 15) n
)
SELECT
start_time,
(SELECT count(*) FROM event
WHERE first_seen < end_time AND last_seen > start_time
AND severity = 5) red,
(SELECT count(*) FROM event
WHERE first_seen < end_time AND last_seen > start_time
AND severity = 4) orange,
(SELECT count(*) FROM event
WHERE first_seen < end_time AND last_seen > start_time
AND severity = 3) yellow
FROM intervals;
我还有(first_seen, last_seen, severity)
的索引
我的问题是它看起来太慢了
该表有大约10万行,并且100个间隔需要10秒。索引扫描似乎太慢了。
如何优化此查询的任何想法?
答案 0 :(得分:1)
最好的办法是摆脱子选择。
尝试以下内容(未经测试,因此可能包含错误):
WITH intervals AS
(
SELECT
'2016-08-02 00:00:00'::TIMESTAMP
+ (n||' minutes')::INTERVAL AS start_time,
'2016-08-02 00:00:00'::TIMESTAMP
+ ((n + 15)||' minutes')::INTERVAL AS end_time
FROM generate_series(0, 24 * 60, 15) n
)
SELECT
start_time,
sum(CASE WHEN severity = 5 THEN 1 ELSE 0 END) red,
sum(CASE WHEN severity = 4 THEN 1 ELSE 0 END) orange,
sum(CASE WHEN severity = 3 THEN 1 ELSE 0 END) yellow
FROM event
RIGHT OUTER JOIN intervals
ON first_seen < end_time AND last_seen > start_time
GROUP BY start_time;
ORDER BY start_time;
您可以通过first_seen
和last_seen
上的两个索引加快速度。多列索引无济于事。