在 Postgrsql 13.5 上 - 我有一个 SELECT 语句,其中存储过程作为 PK 列 (id) 的条件。事实证明这非常慢:
select * from xyz where id=myfunction('static-parameter') -- very slow
但将其分成两个语句,速度非常快。例如
select myfunction('static-parameter') -- Very fast
==> 123
select * from xyz where id=123; -- very fast
我只能假设 postgres 正在为每一行运行该函数。但为什么?以及如何避免这种情况?这是我的真实案例并进行解释分析。
# explain analyze select * from users where id = find_user_by_ip('10.255.0.3');
QUERY PLAN
----------------------------------------------------------------------------------------------------------------
Seq Scan on users (cost=0.00..163.66 rows=1 width=113) (actual time=3214.990..4868.484 rows=1 loops=1)
Filter: (id = find_user_by_ip('10.255.0.3'::character varying))
Rows Removed by Filter: 592
Planning Time: 0.074 ms
Execution Time: 4868.502 ms
(5 rows)
# explain analyze select find_user_by_ip('10.255.0.3');
QUERY PLAN
--------------------------------------------------------------------------------------
Result (cost=0.00..0.26 rows=1 width=4) (actual time=29.522..29.522 rows=1 loops=1)
Planning Time: 0.059 ms
Execution Time: 31.159 ms
(3 rows)
# explain analyze select * from users where id = 487;
QUERY PLAN
------------------------------------------------------------------------------------------------------------------------------------
Index Scan using users_id_key on users (cost=0.28..8.29 rows=1 width=113) (actual time=0.009..0.011 rows=1 loops=1)
Index Cond: (id = 487)
Planning Time: 0.299 ms
Execution Time: 0.031 ms
(4 rows)
您的函数(不是存储过程,这在 PostgreSQL 中是不同的)可能被标记为易失性的。您可能应该更改该函数,以便将其标记为稳定或不可变(当然假设其中之一是正确的),然后它应该很好地使用索引。
用这个: