Dea*_*gor 7 postgresql performance query-performance
我有一个大约有 100M 行的表。它每天只插入一次数据,但我们需要做select很多事情。该selects为通常比较简单,但需要有时返回几千行的100S。
它基于三列node_id,是唯一的pricedate,hour分别是整数、时间戳、整数。大多数查询都很慢,但我将它聚集到node_id,pricedate这解决了大多数查询的缓慢问题。这些查询属于以下类型:
select * from mytable where node_id in (1,2,3,4)
Run Code Online (Sandbox Code Playgroud)
我们仍然偶尔需要做这样的查询:
select * from mytable where pricedate>='2016-05-01'
Run Code Online (Sandbox Code Playgroud)
这些仍然很慢,因为它是由node_id第一个聚集的。我们已经有了一个索引pricedate。问题是用户通常需要足够的数据,查询引擎会抛出索引并使用 seq 扫描。一旦它使用了 seq 扫描,它就会从以查询方式对数据进行聚类中受益匪浅。这导致了我遇到的问题,其中一些查询从一个聚类中受益,而其他查询从另一个中受益:
如果有一种方法可以拥有表的两个物理副本,其中一个副本以一种方式聚集,另一个以另一种方式聚集,但用户对它的访问似乎只有一张表,并且数据库引擎将确保它们是同步的。显然,这样做会受到写入处罚,但这对我们的使用来说无关紧要。
这样的事情可能吗?
我猜没有一种内置的方式来做我所描述的。无论如何,我想我会mytable_dup使用相同的唯一键约束调用一个表,但使用备用集群,然后设置触发器在插入/更新/删除主服务器时插入它。这似乎可行,但从这里开始,是否有一种合理的方法select可以有效地从复制表中提取?
我在家里运行 PostgreSQL 9.4,在 Google 上运行 9.5。
要将数据保存在两个不同的物理序列中,必须将数据存储两次。这可以通过定义第二个覆盖索引来实现。覆盖索引包含查询所需的所有列。这样优化器就不需要参考基表来读取更多的值,并且不太可能恢复到查询计划的基表扫描。优化器执行仅索引扫描。由于索引的选择是由优化器而不是程序员做出的,因此无需更改应用程序代码即可在读取期间利用。在写入期间不需要其他对象来保持一致性。
WHERE 子句中使用的列将是索引的前导列。其他列的顺序不重要。当 PostgreSQL 支持 INCLUDE 语法时,可以更改此索引以使用它。
缺点包括 a) 额外的磁盘来存储此数据 b) 写入期间维护索引的额外延迟 c) 重组等所需的更多系统维护,以及 d) 随着查询的更改,覆盖索引必须更改以匹配 e ) 相应地更大和更长的备份和恢复。
| 归档时间: |
|
| 查看次数: |
72 次 |
| 最近记录: |