sql - 多分区Postgres表的高效查询

标签 sql performance postgresql partitioning

我刚刚重组了我的数据库以使用 partitioning在 Postgres 8.2 中。现在我遇到了查询性能问题:

SELECT *
FROM my_table
WHERE time_stamp >= '2010-02-10' and time_stamp < '2010-02-11'
ORDER BY id DESC
LIMIT 100;

表中有 4500 万行。在分区之前,这将使用反向索引扫描并在达到限制时立即停止。

分区后(在 time_stamp 范围内),Postgres 对主表和相关分区进行全索引扫描并合并结果,对它们进行排序,然后应用限制。这花费的时间太长了。

我可以用:

SELECT * FROM (
  SELECT *
  FROM my_table_part_a
  WHERE time_stamp >= '2010-02-10' and time_stamp < '2010-02-11'
  ORDER BY id DESC
  LIMIT 100) t
UNION ALL
SELECT * FROM (
  SELECT *
  FROM my_table_part_b
  WHERE time_stamp >= '2010-02-10' and time_stamp < '2010-02-11'
  ORDER BY id DESC
  LIMIT 100) t
UNION ALL
  ... and so on ...
ORDER BY id DESC
LIMIT 100

这运行得很快。时间戳超出范围的分区甚至不包含在查询计划中。

我的问题是:在 Postgres 8.2 中是否可以使用一些提示或语法来防止查询计划程序扫描整个表但仍然使用仅引用主表的简单语法?

基本上,我是否可以避免在当前定义的每个分区上动态构建大型 UNION 查询的痛苦?

编辑:我启用了 constraint_exclusion(感谢@Vinko Vrsalovic)

最佳答案

您是否尝试过约束排除(您链接到的文档中的第 5.9.4 节)

Constraint exclusion is a query optimization technique that improves performance for partitioned tables defined in the fashion described above. As an example:

 SET constraint_exclusion = on; 
 SELECT count(*) FROM measurement WHERE logdate >= DATE '2006-01-01'; 

Without constraint exclusion, the above query would scan each of the partitions of the measurement table. With constraint exclusion enabled, the planner will examine the constraints of each partition and try to prove that the partition need not be scanned because it could not contain any rows meeting the query's WHERE clause. When the planner can prove this, it excludes the partition from the query plan.

You can use the EXPLAIN command to show the difference between a plan with constraint_exclusion on and a plan with it off.

关于sql - 多分区Postgres表的高效查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2236776/

相关文章:

mysql - 与数据库触发器相比,Hibernate 的拦截器效率如何?

performance - 用于计算矩阵元素之间边界的脚本

c++ - 在 C++ 中查找程序的运行时间

django - 查询速度反转 OneToOneField

带有日期范围分析的 MYSQL 交叉表 : days as rows, sum as columns

java - MySQL 级联删除错误方向的更改(eclipselink 作为 JPA)

sql - PostgreSQL:如何选择给定日期范围内每一天每个帐户的最后余额?

sql - 如何在 Postgresql 中使用 ALTER 将 VARCHAR 类型更改为 DATETIME?

postgresql - CONSTRAINT 检查远程相关表中的值(通过连接等)

postgresql - 使用动态列名创建数据透视表