优化PostgreSQL中的聚合函数和排序



我有下表 'medicion' 包含以下字段:

id_variable[int](PK), 
id_departamento[int](PK), 
fecha [date](PK), 
valor [number]`.

因此,我想通过id_variable获得对所有数据进行分组的最小值、最大值和平均值。所以我的查询是:

SELECT AVG(valor), MIN(valor), MAX(valor)
FROM medicion
GROUP BY id_variable;

知道默认情况下PostgreSQL为主键构建索引

(id_departamento, id_variable, fecha)

如何优化此查询?,我应该仅通过id_variable创建新索引,还是默认索引在此查询中有效?

谢谢!

由于有一个 avg((,并且需要所有值来计算平均值,它将读取整个表。除非你使用 WHERE,但没有 WHERE,所以我假设你想要全局统计数据。

额外的覆盖指数带来的唯一好处是:

  • 不读取整个表。

如果有 50 列或 TEXT 使表文件变大,这可能是有益的。在这种情况下,读取整个表格只是为了平均几个 int,就需要从磁盘中磨出大量无用的东西。

我的意思是,当您想从一个巨大的表中狙击一两列并将小列设置在缓存中时,覆盖索引非常棒。但这里不是这样,你只有小列,所以这个原因出来了。

  • 。当然,由于索引需要更新,因此更新速度稍慢。此外,索引需要缓存,它将使用一些 RAM 等。

  • 对行进行预排序以方便聚合。

这在这里可能很重要,主要是如果它避免了巨大的排序。但是,如果它避免了哈希聚合,无论如何它都超级快,就不是那么有用了。

现在,如果您的id_variable值相对较少...比如说,足以放入哈希聚合中,这可能是一个相当大的数量,这取决于你的work_mem......那么就很难打败它了...

如果表不经常更新,或者仅插入,并且您经常需要统计信息,请考虑实例化视图(将每个id_variable的最小/最大/平均值保留在单独的表中,并在每次插入时保持更新(。更新 mat 视图需要时间,因此如果您经常需要统计数据,这是一个权衡。

如果您不介意统计数据过时,您可以将统计数据保存在缓存中。

或者,如果你的表有大量旧数据,你可以对它进行分区,并保留旧只读分区的最小/max/sum/count,并且只计算新内容的统计信息。

最新更新