SELECT T.id_task,
T.group,
A.type
FROM TASK T
JOIN ACTION A ON T.id_task = A.id_task
WHERE T.dt_inc BETWEEN 1511146800000 AND 1511492399999
AND A.dt_scheduled BETWEEN 1511146800000 AND 1511492399999
AND A.id_action > ( SELECT MIN(id_action) FROM ACTION WHERE T.id_task = id_task AND type <> 'TRANSFER' )
原始查询要大得多,但有问题的部分就在这里。
仅需一分钟即可完成,仅使用(task.dt_inc,action.dt_scheduled),但如果我 DROP INDEX action_dt_scheduled ,则执行时间将降至一秒,仅使用相同的结果(任务.dt_inc,action.id_task)索引。
我重新创建了索引DROP&gt;创建,我使REINDEX wath应该与重新创建相同,我现在能做什么?
修改
我试图获得慢查询的EXPLAIN,但这不再慢了,表的ANALYZE和REINDEX解决了这个问题。
答案 0 :(得分:2)
有更多理由说明如果没有它,索引的性能可能会更差:
错误的估计 - 当使用索引时,则使用随机io。随机io通常比seq扫描慢得多 - 但如果index选择表的一小部分,那么它是可以接受的。但是当计划者对结果的估计结果不好时,可以使用索引,尽管seq扫描更好。您可以通过EXPLAIN ANALYZE query
命令检查估算值。
膨胀的索引 - 如果没有重新索引长时间索引,索引的状态可能会很糟糕 - 那么索引的访问和使用可能会很慢。
错误大小的effective_cache_size
参数 - 当此参数不准确或不安全时,索引页可以从RAM推送堆(表)页。在这种情况下,页面缓存(共享缓冲区)不稳定 - 您可以使用pg_buffercache
扩展名检查共享缓冲区的稳定性。太低的shared_buffers
可能会产生类似的效果。