gpt4 book ai didi

sql - 带日期时间的 WHERE 子句的索引等

转载 作者:行者123 更新时间:2023-11-29 11:32:57 25 4
gpt4 key购买 nike

我使用的是 Postgres 9.1,查询执行速度非常慢。

查询:

Explain Analyze SELECT COUNT(DISTINCT email) FROM "invites" WHERE (
created_at < '2012-10-10 21:08:05.259200'
AND invite_method = 'email'
AND accept_count = 0
AND reminded_count < 3
AND (last_reminded_at IS NULL OR last_reminded_at < '2012-10-10 21:08:05.261483'))

结果:

Aggregate  (cost=19828.24..19828.25 rows=1 width=21) (actual time=11395.903..11395.903 rows=1 loops=1)
-> Seq Scan on invites (cost=0.00..18970.57 rows=343068 width=21) (actual time=0.036..353.121 rows=337143 loops=1)
Filter: ((created_at < '2012-10-10 21:08:05.2592'::timestamp without time zone) AND (reminded_count < 3) AND ((last_reminded_at IS NULL) OR (last_reminded_at < '2012-10-10 21:08:05.261483'::timestamp without time zone)) AND ((invite_method)::text = 'email'::text) AND (accept_count = 0))
Total runtime: 11395.970 ms

如您所见,这大约需要 11 秒。我将如何添加索引来优化此查询性能?

最佳答案

只需索引“一切”,如 Jim advises不是一个非常有效的策略。索引会带来维护成本,将许多单独的索引组合在一起(维护和查询)比一个定制索引更昂贵。这始终取决于您的完整情况。

对于只读或很少写入的表,索引成本较低,但对于具有大量写入操作的 volatile 表,索引成本较高。另一个缺点是索引禁止热更新(仅堆元组)更改涉及的列。见:

如果特定查询的性能很重要,partial multi-column index将是一个很好的策略。特化,但比所有相关列上的单个索引更便宜、更快。经验法则是......

  • 将易变条件的列(因查询而异)放入索引中。
  • WHERE 子句中使用稳定条件(对每个查询都相同)来缩小索引的分区。

从您的列名(由于缺乏信息)来看,accept_count = 0 似乎是这里最具选择性(和稳定)的过滤器,而 created_atlast_reminded_at 可能会不断变化。所以也许是这样的:

CREATE INDEX invites_special_idx
ON invites (created_at, last_reminded_at)
WHERE accept_count = 0
AND invite_method = 'email'
AND reminded_count < 3;

排序 created_atlast_reminded_at ascending 以完美匹配查询 - 这恰好是默认设置。这样,系统可以在单次扫描中从索引顶部获取所有相关行。应该很快。

正如我们在您之前的一个问题中所讨论的那样,将表聚集在索引上可能会有额外的帮助。请务必阅读有关 CLUSTER 的手册.
正如@Craig 提供的那样,您不能在部分索引上 CLUSTER 。由于 CLUSTER 是一次性操作(效果会随着以后的写入操作而降低),您可以通过创建一个完整 索引来规避此限制,CLUSTER表并再次删除索引。喜欢:

CREATE INDEX invites_special_idx2 ON invites (created_at, last_reminded_at);
CLUSTER invites USING invites_special_idx2;
DROP INDEX invites_special_idx2;

CLUSTER 仅在没有其他重要查询与数据分布要求相矛盾时才有用。

PostgreSQL 9.2 有几个新功能可以使您的查询更快。特别是仅索引扫描 ( first item in the release notes )。考虑升级。

关于sql - 带日期时间的 WHERE 子句的索引等,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12923558/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com