在 postgresql 中优化潜在客户查询
Posted
技术标签:
【中文标题】在 postgresql 中优化潜在客户查询【英文标题】:Optimising a Lead query in postgresql 【发布时间】:2019-03-05 15:02:35 【问题描述】:我想根据其名称和字母顺序选择一个实体,选择下一行的name
。 name
列是一个 varchar,是唯一的并且有一个索引。
使用Lead 窗口函数,这是我想出的:
SELECT *
FROM (
SELECT
*,
LEAD("name", 1, '') OVER(ORDER BY name) AS next
FROM entity
ORDER BY "name"
) results
WHERE "name" = 'CACTUS';
但是,随着实体表大小的增加,查询性能会下降。
查询计划如下:
Subquery Scan on results (cost=0.42..31205.95 rows=1 width=299)
Filter: ((results.""name"")::text = 'CACTUS'::text)"
-> WindowAgg (cost=0.42..29002.24 rows=176297 width=299)"
-> Index Scan using ""IDX_2fbbd02c0f1ee2a4dda593705d"" on entity (cost=0.42..26357.79 rows=176297 width=235)"
有没有更有效的方法来做到这一点?
postgresql 版本 11+
【问题讨论】:
lead()
没有 order by 并没有真正意义上的开始 - 没有“下一行”之类的东西,除非你指定一个 order by
。但是是的,预计您拥有的行越多,这会越慢,因为内部查询必须对表中的 所有行进行排序
好的,我假设它会使用子查询的顺序,我已经更新了窗口函数以具有明确的 ORDER BY。
【参考方案1】:
您可以尝试不使用窗口函数和相关的标量子查询,但我不确定这是否真的更快:
SELECT e1.name,
(select coalesce(max(name), '')
from entity e2
where e2.name > e1.name) as next
FROM entity e1
WHERE e1.name = 'CACTUS';
【讨论】:
谢谢,这对我来说工作速度要快几个数量级,但我必须在子查询和查询中添加ORDER BY
。我还更新了问题以反映我想要一个订单:D。如果几天后没有其他答案,我会接受这个答案。
@shusson:但您声称 name
是唯一的,因此条件 where e1.name = 'CACTUS'
只能返回一行 - 我不明白您为什么需要 order by
。 max()
和 >
的使用确实对选择“下一个”名称施加了顺序
是的,但我对基于特定顺序的下一行的名称感兴趣,比如按字母顺序。
@shusson:条件e2.name > e1.name
强加命令
是的,我会更新问题以强制按字母顺序以上是关于在 postgresql 中优化潜在客户查询的主要内容,如果未能解决你的问题,请参考以下文章