作者介绍
1. 绑定变量窥视的原理说明
2. 实际测试
2.1 造测试表和数据
1.create table test01(id serial, t text);2.insert into test01(t) select 'tang' from generate_series(1, 1000000);3.insert into test01(t) select 'osdba' from generate_series(1, 2);4.CREATE INDEX idx_test01_t ON test01(t);5.analyze test01;
1.osdba=# explain SELECT count(*) FROM test01 WHERE t = 'tang';2. QUERY PLAN3.------------------------------------------------------------------------------------------4. Finalize Aggregate (cost=12656.23..12656.24 rows=1 width=8)5. -> Gather (cost=12656.01..12656.22 rows=2 width=8)6. Workers Planned: 27. -> Partial Aggregate (cost=11656.01..11656.02 rows=1 width=8)8. -> Parallel Seq Scan on test01 (cost=0.00..10614.34 rows=416668 width=0)9. Filter: (t = 'tang'::text)10.(6 rows)11.12.Time: 1.532 ms13.14.osdba=# explain SELECT count(*) FROM test01 WHERE t = 'osdba';15. QUERY PLAN16.--------------------------------------------------------------------------------------17. Aggregate (cost=4.45..4.46 rows=1 width=8)18. -> Index Only Scan using idx_test01_t on test01 (cost=0.42..4.44 rows=1 width=0)19. Index Cond: (t = 'osdba'::text)20.(3 rows)21.22.Time: 1.484 ms
2.2 按绑定变量的第一次测试
1.PREPARE myplan(text) AS SELECT count(*) FROM test01 WHERE t = $1;
1.osdba-mac:~ osdba$ psql2.psql (10.5)3.Type "help" for help.4.5.osdba=# PREPARE myplan(text) AS SELECT count(*) FROM test01 WHERE t = $1;6.PREPARE7.osdba=# explain EXECUTE myplan('tang');8. QUERY PLAN9.------------------------------------------------------------------------------------------10. Finalize Aggregate (cost=12656.23..12656.24 rows=1 width=8)11. -> Gather (cost=12656.01..12656.22 rows=2 width=8)12. Workers Planned: 213. -> Partial Aggregate (cost=11656.01..11656.02 rows=1 width=8)14. -> Parallel Seq Scan on test01 (cost=0.00..10614.34 rows=416668 width=0)15. Filter: (t = 'tang'::text)16.(6 rows)17.18.osdba=# explain EXECUTE myplan('tang');19. QUERY PLAN20.------------------------------------------------------------------------------------------21. Finalize Aggregate (cost=12656.23..12656.24 rows=1 width=8)22. -> Gather (cost=12656.01..12656.22 rows=2 width=8)23. Workers Planned: 224. -> Partial Aggregate (cost=11656.01..11656.02 rows=1 width=8)25. -> Parallel Seq Scan on test01 (cost=0.00..10614.34 rows=416668 width=0)26. Filter: (t = 'tang'::text)27.(6 rows)28.29.osdba=# explain EXECUTE myplan('tang');30. QUERY PLAN31.------------------------------------------------------------------------------------------32. Finalize Aggregate (cost=12656.23..12656.24 rows=1 width=8)33. -> Gather (cost=12656.01..12656.22 rows=2 width=8)34. Workers Planned: 235. -> Partial Aggregate (cost=11656.01..11656.02 rows=1 width=8)36. -> Parallel Seq Scan on test01 (cost=0.00..10614.34 rows=416668 width=0)37. Filter: (t = 'tang'::text)38.(6 rows)39.40.osdba=# explain EXECUTE myplan('tang');41. QUERY PLAN42.------------------------------------------------------------------------------------------43. Finalize Aggregate (cost=12656.23..12656.24 rows=1 width=8)44. -> Gather (cost=12656.01..12656.22 rows=2 width=8)45. Workers Planned: 246. -> Partial Aggregate (cost=11656.01..11656.02 rows=1 width=8)47. -> Parallel Seq Scan on test01 (cost=0.00..10614.34 rows=416668 width=0)48. Filter: (t = 'tang'::text)49.(6 rows)50.51.osdba=# explain EXECUTE myplan('tang');52. QUERY PLAN53.------------------------------------------------------------------------------------------54. Finalize Aggregate (cost=12656.23..12656.24 rows=1 width=8)55. -> Gather (cost=12656.01..12656.22 rows=2 width=8)56. Workers Planned: 257. -> Partial Aggregate (cost=11656.01..11656.02 rows=1 width=8)58. -> Parallel Seq Scan on test01 (cost=0.00..10614.34 rows=416668 width=0)59. Filter: (t = 'tang'::text)60.(6 rows)61.62.osdba=# explain EXECUTE myplan('tang');63. QUERY PLAN64.------------------------------------------------------------------------------------------65. Finalize Aggregate (cost=12656.23..12656.24 rows=1 width=8)66. -> Gather (cost=12656.01..12656.22 rows=2 width=8)67. Workers Planned: 268. -> Partial Aggregate (cost=11656.01..11656.02 rows=1 width=8)69. -> Parallel Seq Scan on test01 (cost=0.00..10614.34 rows=416668 width=0)70. Filter: (t = $1)71.(6 rows)
1.osdba=# explain analyze EXECUTE myplan('osdba');2. QUERY PLAN3.----------------------------------------------------------------------------------------------------------------------------------------4. Finalize Aggregate (cost=12656.23..12656.24 rows=1 width=8) (actual time=114.069..114.069 rows=1 loops=1)5. -> Gather (cost=12656.01..12656.22 rows=2 width=8) (actual time=113.957..114.865 rows=3 loops=1)6. Workers Planned: 27. Workers Launched: 28. -> Partial Aggregate (cost=11656.01..11656.02 rows=1 width=8) (actual time=106.088..106.088 rows=1 loops=3)9. -> Parallel Seq Scan on test01 (cost=0.00..10614.34 rows=416668 width=0) (actual time=106.072..106.072 rows=1 loops=3)10. Filter: (t = $1)11. Rows Removed by Filter: 33333312. Planning time: 0.035 ms13. Execution time: 115.044 ms14.(10 rows)
2.3 按绑定变量的第二次测试
1.osdba-mac:~ osdba$ psql2.psql (10.5)3.Type "help" for help.4.5.osdba=# PREPARE myplan(text) AS SELECT count(*) FROM test01 WHERE t = $1;6.PREPARE7.osdba=# explain EXECUTE myplan('tang');8. QUERY PLAN9.------------------------------------------------------------------------------------------10. Finalize Aggregate (cost=12656.23..12656.24 rows=1 width=8)11. -> Gather (cost=12656.01..12656.22 rows=2 width=8)12. Workers Planned: 213. -> Partial Aggregate (cost=11656.01..11656.02 rows=1 width=8)14. -> Parallel Seq Scan on test01 (cost=0.00..10614.34 rows=416668 width=0)15. Filter: (t = 'tang'::text)16.(6 rows)17.18.osdba=# explain EXECUTE myplan('tang');19. QUERY PLAN20.------------------------------------------------------------------------------------------21. Finalize Aggregate (cost=12656.23..12656.24 rows=1 width=8)22. -> Gather (cost=12656.01..12656.22 rows=2 width=8)23. Workers Planned: 224. -> Partial Aggregate (cost=11656.01..11656.02 rows=1 width=8)25. -> Parallel Seq Scan on test01 (cost=0.00..10614.34 rows=416668 width=0)26. Filter: (t = 'tang'::text)27.(6 rows)28.29.osdba=# explain EXECUTE myplan('tang');30. QUERY PLAN31.------------------------------------------------------------------------------------------32. Finalize Aggregate (cost=12656.23..12656.24 rows=1 width=8)33. -> Gather (cost=12656.01..12656.22 rows=2 width=8)34. Workers Planned: 235. -> Partial Aggregate (cost=11656.01..11656.02 rows=1 width=8)36. -> Parallel Seq Scan on test01 (cost=0.00..10614.34 rows=416668 width=0)37. Filter: (t = 'tang'::text)38.(6 rows)39.40.osdba=# explain EXECUTE myplan('tang');41. QUERY PLAN42.------------------------------------------------------------------------------------------43. Finalize Aggregate (cost=12656.23..12656.24 rows=1 width=8)44. -> Gather (cost=12656.01..12656.22 rows=2 width=8)45. Workers Planned: 246. -> Partial Aggregate (cost=11656.01..11656.02 rows=1 width=8)47. -> Parallel Seq Scan on test01 (cost=0.00..10614.34 rows=416668 width=0)48. Filter: (t = 'tang'::text)49.(6 rows)50.51.osdba=# explain EXECUTE myplan('osdba');52. QUERY PLAN53.--------------------------------------------------------------------------------------54. Aggregate (cost=4.45..4.46 rows=1 width=8)55. -> Index Only Scan using idx_test01_t on test01 (cost=0.42..4.44 rows=1 width=0)56. Index Cond: (t = 'osdba'::text)57.(3 rows)
1.osdba=# explain EXECUTE myplan('tang');2. QUERY PLAN3.------------------------------------------------------------------------------------------4. Finalize Aggregate (cost=12656.23..12656.24 rows=1 width=8)5. -> Gather (cost=12656.01..12656.22 rows=2 width=8)6. Workers Planned: 27. -> Partial Aggregate (cost=11656.01..11656.02 rows=1 width=8)8. -> Parallel Seq Scan on test01 (cost=0.00..10614.34 rows=416668 width=0)9. Filter: (t = 'tang'::text)10.(6 rows)11.12.osdba=# explain EXECUTE myplan('tang');13. QUERY PLAN14.------------------------------------------------------------------------------------------15. Finalize Aggregate (cost=12656.23..12656.24 rows=1 width=8)16. -> Gather (cost=12656.01..12656.22 rows=2 width=8)17. Workers Planned: 218. -> Partial Aggregate (cost=11656.01..11656.02 rows=1 width=8)19. -> Parallel Seq Scan on test01 (cost=0.00..10614.34 rows=416668 width=0)20. Filter: (t = 'tang'::text)21.(6 rows)22....23....24....25.26.osdba=# explain EXECUTE myplan('osdba');27. QUERY PLAN28.--------------------------------------------------------------------------------------29. Aggregate (cost=4.45..4.46 rows=1 width=8)30. -> Index Only Scan using idx_test01_t on test01 (cost=0.42..4.44 rows=1 width=0)31. Index Cond: (t = 'osdba'::text)32.(3 rows)33....34....35.36.osdba=# explain EXECUTE myplan('tang');37. QUERY PLAN38.------------------------------------------------------------------------------------------39. Finalize Aggregate (cost=12656.23..12656.24 rows=1 width=8)40. -> Gather (cost=12656.01..12656.22 rows=2 width=8)41. Workers Planned: 242. -> Partial Aggregate (cost=11656.01..11656.02 rows=1 width=8)43. -> Parallel Seq Scan on test01 (cost=0.00..10614.34 rows=416668 width=0)44. Filter: (t = 'tang'::text)45.(6 rows)
3. PostgreSQL 12的plan_cache_mode配置参数
· auto: 这时默认值,即默认情况下与PostgreSQL11及以下版本相同的行为。
· force_custom_plan: 相当于关闭绑定变量窥视,永远进行硬解析。
· force_generic_plan: 走通用的固定执行计划(generic plan)
1.osdba-mac:pgdata12 osdba$ psql2.psql (12.1)3.Type "help" for help.4.5.osdba=# PREPARE myplan(text) AS SELECT count(*) FROM test01 WHERE t = $1;6.PREPARE7.osdba=# set plan_cache_mode to force_custom_plan;8.SET9.osdba=# explain EXECUTE myplan('osdba');10. QUERY PLAN11.--------------------------------------------------------------------------------------12. Aggregate (cost=4.45..4.46 rows=1 width=8)13. -> Index Only Scan using idx_test01_t on test01 (cost=0.42..4.44 rows=1 width=0)14. Index Cond: (t = 'osdba'::text)15.(3 rows)16.17.osdba=# explain EXECUTE myplan('tang');18. QUERY PLAN19.------------------------------------------------------------------------------------------20. Finalize Aggregate (cost=12656.23..12656.24 rows=1 width=8)21. -> Gather (cost=12656.01..12656.22 rows=2 width=8)22. Workers Planned: 223. -> Partial Aggregate (cost=11656.01..11656.02 rows=1 width=8)24. -> Parallel Seq Scan on test01 (cost=0.00..10614.34 rows=416668 width=0)25. Filter: (t = 'tang'::text)26.(6 rows)

文章转载自PostgreSQL中文社区,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




