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