我有这样一种情况,运行一个过滤分区表中索引列的查询时,会执行全表扫描。
显然,在PostgreSQL中,这是一个已知的问题,并且在这里有详细解释。
除了对每个分区执行查询,然后对所有结果执行UNION之外,是否还有更优雅的方法来解决这个问题?
我有这样一种情况,运行一个过滤分区表中索引列的查询时,会执行全表扫描。
显然,在PostgreSQL中,这是一个已知的问题,并且在这里有详细解释。
除了对每个分区执行查询,然后对所有结果执行UNION之外,是否还有更优雅的方法来解决这个问题?
在PostgreSQL中,索引可以良好地进行有关分区的扫描。但是,你必须正确设置所有内容才能使其正常工作,并且很容易错过http://www.postgresql.org/docs/current/static/ddl-partitioning.html中所记录的众多步骤之一。
最重要的是要认识到,为了避免顺序扫描,你必须提供足够的信息,以便PostgreSQL可以证明某些分区不可能具有你正在查找的数据; 然后跳过它们作为查询结果的潜在来源。你链接的文章指出这是顺序扫描问题的解决方案:“如果将范围约束添加到每个分区的日期字段中,则可以将此查询优化为一个循环,其中您首先查询“最新”分区,然后向后工作,直到找到一个单个值高于所有剩余分区的范围。”但并没有显示更改后会看到的改进计划。
你可能犯了一些常见的错误:
- postgresql.conf文件中的constraint_exclusion参数默认关闭。在默认情况下,你将得不到预期的结果。
-未使用CHECK创建非重叠分区,这会使规划程序无法知道每个分区中的内容。可能会错过此步骤,但仍然可以将数据正确放入正确的分区中,只是规划程序不会知道。
-没有在每个分区上放置索引,只在主表上创建了一个索引。这将使你仅获得有关相关分区的顺序扫描,因此并不像上述问题那样糟糕,但也不好。
在即将发布的PostgreSQL版本中可以更轻松地进行所有这些操作(在8.4中设置constraint_partition相当自动化,并正在努力开发某种分区设置自动化)。现在,如果你仔细遵循说明并避免所有这些问题,应该工作正常。