有没有办法避免由于函数未被识别为索引的一部分而导致的Sort
操作?该功能不会真正影响.GROUP BY
DATE_TRUNC
tstamp
ix
ix
CREATE INDEX ix ON tbl(col, tstamp, num)
SELECT col,
DATE_TRUNC('MONTH', tstamp AT TIME ZONE 'UTC') AS trunc,
SUM(num)
FROM tbl
WHERE col IN (?, ?, ...)
AND tstamp >= ?
AND tstamp < ?
GROUP BY col, trunc
精度参数DATE_TRUNC
是动态的,它也可以是'DAY'
或'YEAR'
……所以如果不为每个变体创建索引,我就无法索引该函数。
我得到的执行计划:
Finalize GroupAggregate
Group Key: col, DATE_TRUNC('MONTH', tstamp AT TIME ZONE 'UTC')
-> Gather Merge
Workers Planned: 2
Workers Launched: 2
-> Partial GroupAggregate
Group Key: col, DATE_TRUNC('MONTH', tstamp AT TIME ZONE 'UTC')
-> Sort
Sort Key: col, DATE_TRUNC('MONTH', tstamp AT TIME ZONE 'UTC')
Sort Method: external merge Disk: ...kB
-> Parallel Index Only Scan using ix on tbl
Index Cond: ((col = ANY (...)) AND (tstamp >= ...) AND (tstamp < ...))
Heap Fetches: 0
我想要的执行计划看起来像这样:
GroupAggregate
Group Key: col, DATE_TRUNC('MONTH', tstamp AT TIME ZONE 'UTC')
-> Index Only Scan using ix on tbl
Index Cond: ((col = ANY (...)) AND (tstamp >= ...) AND (tstamp < ...))
Heap Fetches: 0
(如果我不使用,我会明白DATE_TRUNC
)
没有办法避免使用您的查询进行排序,因为 PostgreSQL 不知道索引扫描返回的行是否会正确排序,并且组聚合需要排序输入。
你唯一的机会是增加
work_mem
,直到你得到一个不需要排序输入的哈希聚合。