常见问题
- Q:自动参数化是否存在计划跳变问题?
A:在自动参数化下,部分语句计划可能会发生变化。由于自动参数化将语句中的常量替换为参数,再进行绑参执行。在计划生成的过程中,部分场景下对常量及参数的处理有区别,因此导致设置cursor_sharing = force后,出现部分计划跳变的问题。
如下示例中,SELECT * FROM cursor_sharing_tbl WHERE col1 = 1;在cursor_sharing = off场景使用索引扫描,在cursor_sharing = force场景下使用全表扫描。
gaussdb=# CREATE TABLE cursor_sharing_tbl(col1 int, b int); CREATE TABLE gaussdb=# CREATE INDEX cursor_sharing_tbl_idx ON cursor_sharing_tbl(col1) WHERE col1 != 0; CREATE INDEX gaussdb=# SET plan_cache_mode = 'force_generic_plan'; SET gaussdb=# SET cursor_sharing = off; SET gaussdb=# EXPLAIN SELECT * FROM cursor_sharing_tbl WHERE col1 = 1; QUERY PLAN -------------------------------------------------------------------------------------- Bitmap Heap Scan on cursor_sharing_tbl (cost=1.36..9.58 rows=11 width=8) Recheck Cond: (col1 = 1), (Expression Flatten Optimized) -> Bitmap Index Scan on cursor_sharing_tbl_idx (cost=0.00..1.36 rows=11 width=0) Index Cond: (col1 = 1) (4 rows) gaussdb=# SET cursor_sharing = force; SET gaussdb=# EXPLAIN SELECT * FROM cursor_sharing_tbl WHERE col1 = 1; QUERY PLAN -------------------------------------------------------------------- [Parameterized] Seq Scan on cursor_sharing_tbl (cost=0.00..36.86 rows=11 width=8) Filter: (col1 = $1), (Expression Flatten Optimized) (3 rows) gaussdb=# DROP TABLE cursor_sharing_tbl CASCADE; DROP TABLE该场景由于自动参数化将SELECT * FROM cursor_sharing_tbl WHERE col1 = 1;中常量1作为参数生成计划,在设置plan_cache_mode = 'force_generic_plan';强制走gplan的场景,会导致cursor_sharing_tbl_idx部分索引的索引条件为参数,索引失效,因此使用全表扫描。
计划跳变场景可通过设置plan_cache_mode = 'force_custom_plan';强制走cplan解决,或关闭自动参数化解决。
- Q:自动参数化及相同语句计划复用是否存在计划缓存过多问题?
A:自动参数化及相同语句计划复用机制通过缓存已执行语句的执行计划,避免在相同语句场景下重复生成执行计划,从而提高查询执行效率。然而,此机制可能导致执行计划缓存占用过多内存。当前系统已启用计划缓存上限管控功能。若观察到session级计划缓存占用异常,可调整max_plancache_memory_ratio参数进行优化。