我们有一张包含每月约10亿条记录的表格。考虑到18个月的历史数据,我们就需要处理大约180亿条记录。
该表格按照日期每周分区(因此我们大约有74个分区)。
对于我们的某个查询,我们需要获取一个指定单元最近的1000条记录。类似这样:
问题在于,我们在解释中得到了以下结果:
问题是,考虑到我们按obs_time排序,有没有一种方法使查询使用分区并仅搜索所需的前n个分区?
在大多数情况下,结果将在最近的4个分区中(因此只会搜索这4个分区),而只有在极少数情况下才需要搜索所有分区。
如果在按顺序获取n个分区后发现了1000个结果,则不会考虑其余分区(舍弃了数十亿条记录)。测试/解释表明PostgreSQL没有这样做。实际上,它正在寻找所有分区(如果没有得到WHERE状态来限制QUERY到PARTITIONS的约束条件。是否有一种方法强制执行此操作?(例如,在ORACLE中,可以向DB引擎提供有关如何执行某些查询的建议,尽管我也不知道是否对分区执行此操作)
手动执行每个分区(给出间隔)的开销会导致更差的结果(这样做实际上可能是在没有分区的情况下工作,最好有不同的表)。
还有其他建议吗?
该表格按照日期每周分区(因此我们大约有74个分区)。
对于我们的某个查询,我们需要获取一个指定单元最近的1000条记录。类似这样:
SELECT code, obs_time
FROM unit_position
WHERE unit_id = 1
ORDER BY obs_time DESC LIMIT 1000;
问题在于,我们在解释中得到了以下结果:
Limit (cost=96181.06..96181.09 rows=10 width=12)
-> Sort (cost=96181.06..102157.96 rows=2390760 width=12)
Sort Key: unit_position .obs_time -> Result (cost=0.00..44517.60 rows=2390760 width=12) -> Append (cost=0.00..44517.60 rows=2390760 width=12) -> Seq Scan on unit_position (cost=0.00..42336.00 rows=2273600 width=12) -> Seq Scan on unit_position_week350 unit_position (cost=0.00..21.60 rows=1160 width=12) -> ... (ALL OTHER PARTITIONS) ... -> Seq Scan on unit_position_week450 unit_position (cost=0.00..21.60 rows=1160 width=12)
另一方面,如果我们得到这样的查询(将查询限制在我们可以获取1000条记录的第一个间隔内),我们可以获得比原来快两倍的结果:
SELECT fake, obs_time
FROM unit_position
WHERE unit_id = 1
AND obs_time >= NOW() - '7 weeks'::interval
ORDER BY obs_time DESC LIMIT 1000;
问题是,考虑到我们按obs_time排序,有没有一种方法使查询使用分区并仅搜索所需的前n个分区?
在大多数情况下,结果将在最近的4个分区中(因此只会搜索这4个分区),而只有在极少数情况下才需要搜索所有分区。
如果在按顺序获取n个分区后发现了1000个结果,则不会考虑其余分区(舍弃了数十亿条记录)。测试/解释表明PostgreSQL没有这样做。实际上,它正在寻找所有分区(如果没有得到WHERE状态来限制QUERY到PARTITIONS的约束条件。是否有一种方法强制执行此操作?(例如,在ORACLE中,可以向DB引擎提供有关如何执行某些查询的建议,尽管我也不知道是否对分区执行此操作)
手动执行每个分区(给出间隔)的开销会导致更差的结果(这样做实际上可能是在没有分区的情况下工作,最好有不同的表)。
还有其他建议吗?