volatile 函数影响子查询提升
我们知道 volatile 函数会影响SQL的执行性能,比如:volatile 类型函数无法建函数索引、volatile 函数针对每条记录都要执行一次。本篇的例子主要讲述 volatile 类型的函数还会影响子查询的提升。
1、构建例子
1 2 3 4 5 6 | create table t1(id1 integer ,name1 varchar (9),addr1 text); create table t2(id2 integer ,name2 varchar (9),addr2 text); insert into t1 select generate_series(1,1000000),generate_series(1,1000000), 'abc' ; insert into t2 select generate_series(1,1000000),generate_series(1,1000000), 'abc' ; create index ind_t1 on t1(id1); create index ind_t2 on t2(id2); |
2、volatile 函数与执行计划
对于 t2 表的访问无法使用索引。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | test=# \df+ replace List of functions Schema | Name | Result data type | Argument data types | Type | Volatility | Parallel | Owner | Security | Access privileges | Language | Source code | Description --------+---------+-------------------+---------------------+------+------------+----------+--------+----------+-------------------+----------+---------------------------------+------------- sys | replace | character varying | text, text, text | func | volatile | safe | system | invoker | | c | ora_replace_text | test=# explain select id1,name1 from t1 a ,( select id2, replace (id2, 'b' , 'B' ) name2 from t2 ) b where a.id1=b.id2 and name1= '123' ; QUERY PLAN --------------------------------------------------------------------- Hash Join (cost=17935.01..52120.02 rows =1 width=10) Hash Cond: (t2.id2 = a.id1) -> Seq Scan on t2 (cost=0.00..20435.00 rows =1000000 width=36) -> Hash (cost=17935.00..17935.00 rows =1 width=10) -> Seq Scan on t1 a (cost=0.00..17935.00 rows =1 width=10) Filter: ((name1)::text = '123' ::text) (6 rows ) |
不使用子查询情况下的,可以使用索引:
1 2 3 4 5 6 7 8 9 | test=# explain select id1,name1,id2, replace (id2, 'b' , 'B' ) name2 from t1 a,t2 b where a.id1=b.id2 and name1= '123' ; QUERY PLAN ------------------------------------------------------------------------------ Nested Loop (cost=0.42..17943.46 rows =1 width=46) -> Seq Scan on t1 a (cost=0.00..17935.00 rows =1 width=10) Filter: ((name1)::text = '123' ::text) -> Index Only Scan using ind_t2 on t2 b (cost=0.42..8.44 rows =1 width=4) Index Cond: (id2 = a.id1) (5 rows ) |
3、immutable 函数与执行计划
改成immutable 函数后,子查询可以提升,从而能够使用索引。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | test=# \df+ replace List of functions Schema | Name | Result data type | Argument data types | Type | Volatility | Parallel | Owner | Security | Access privileges | Language | Source code | Description --------+---------+-------------------+---------------------+------+------------+----------+--------+----------+-------------------+----------+---------------------------------+------------- sys | replace | character varying | text, text, text | func | immutable | safe | system | invoker | | c | ora_replace_text | test=# explain select id1,name1 from t1 a ,( select id2, replace (id2, 'b' , 'B' ) name2 from t2 ) b where a.id1=b.id2 and name1= '123' ; QUERY PLAN ---------------------------------------------------------------------------- Nested Loop (cost=0.42..17943.45 rows =1 width=10) -> Seq Scan on t1 a (cost=0.00..17935.00 rows =1 width=10) Filter: ((name1)::text = '123' ::text) -> Index Only Scan using ind_t2 on t2 (cost=0.42..8.44 rows =1 width=4) Index Cond: (id2 = a.id1) (5 rows ) |
KINGBASE研究院
分类:
性能相关
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!