我有一个看起来像这样的查询:
SELECT
DISTINCT "articles"."id",
"articles"."company_uuid",
"articles"."status",
"articles"."discount_reference",
"articles"."created_at"
--- more columns
FROM
"articles"
INNER JOIN "customers" ON "customers"."rec" = 'f'
AND "customers"."article_id" = "articles"."id"
WHERE
"articles"."type" = 'sending_request'
AND "articles"."hidden" = 'f'
AND "articles"."discount_reference" = 'Discount/737251623'
AND "articles"."api_domain" = 'company'
AND "articles"."status" IN ('completed', 'active')
AND (customers.search_text ILIKE unaccent('%verb%'))
ORDER BY
authored_on DESC NULLS LAST
LIMIT
20 OFFSET 0;
第一个查询很慢,但当我重新运行时它总是更快。当我比较计划时,我没有看到明确的答案。我有一个用于客户搜索文本的杜松子酒三元组索引。
https://explain.dalibo.com/plan/b11657f576699fa8
第二轮
https://explain.dalibo.com/plan/g81h74b9g521g5e7
IO 和缓冲区的差异是差异的根源吗?
我在 RDS 上运行 PostgreSQL 14。
TL/DR:冷缓存。
如果只有第一次执行很慢,那么它通常是冷缓存。而你的情况就是这样。
正如您在图像中的 IO & Buffers 下看到的(已经让您感到疑惑),快速查询执行只有命中,没有读取。这意味着,以后的执行会受益于现在填充的缓存。
通常,更多的 RAM(以及相应的 Postgres 的更多可用缓存)、更快的存储、更少浪费的数据库设计和/或优化的查询会有所帮助。
如果只是第一个查询速度慢的问题,预热缓存可能会解决问题。看:
除此之外,这个查询可能会做得更好,避免不必要的和昂贵的
DISTINCT
。但是,不会消除冷缓存的一般问题。这是假设
created_at
是真的articles.created_at
,并且articles.id
是 PK。