
# 会话级计划缓存管控
#### 前提条件
- 启用逻辑内存管理模块，将enable_memory_limit参数设置为on，具体设置请参见《参考》中"数据库运行参数说明 \> GUC参数说明 \> 资源消耗 \> 内存"章节。设置成功后，重启数据库集群。
- 打开会话级计划缓存管控。 将GUC参数max_plancache_memory_ratio设置为大于0的取值。
  
 
#### 语法
通过gsql创建PREPARE语句，或通过JDBC创建PREPARE语句。
- 通过gsql创建：
  ```
  PREPARE name [ ( data_type [, ...] ) ] AS statement;
  ```
  
- 通过JDBC创建：
  ```
  PreparedStatement pstmt = connection.prepareStatement(sql);
  ```
  
 
#### 注意事项
1. 会话级计划缓存管控仅支持管控PREPARE语句和自动参数化创建的计划缓存，不支持管控通过存储过程创建的计划缓存。
2. 缓存淘汰策略只在执行计划创建、重建后内存大小达到或超过上限后触发。
 
#### 操作步骤
1. 打开逻辑内存管理模块以及设置会话级计划缓存管控，将enable_memory_limit参数设置为on，具体设置请参见《参考》中"数据库运行参数说明 \> GUC参数说明 \> 资源消耗 \> 内存"章节。设置成功后，重启数据库集群。
   ```
   SET max_plancache_memory_ratio = 60;
   ```
   

2. 创建大量PREPARE语句。
3. 观察内存视图，在计划缓存大小达到阈值后不再增长，且PREPARE语句视图中，存在计划被淘汰的场景（即GS_ALL_PREPARED_STATEMENTS视图的is_deleted列值为t）。
 
#### 示例
```
gaussdb=# CREATE TABLE plancache_memctl_tbl (col1 int, col2 varchar(10));
NOTICE:  The 'DISTRIBUTE BY' clause is not specified. Using 'col1' as the distribution column by default.
HINT:  Please use 'DISTRIBUTE BY' clause to specify suitable data distribution column.
CREATE TABLE
gaussdb=# INSERT INTO plancache_memctl_tbl (col1, col2) VALUES (1, 'test');
INSERT 0 1
gaussdb=# SET max_plancache_memory_ratio=60;
SET
gaussdb=# SET plan_cache_mode=force_generic_plan;
SET
gaussdb=# PREPARE p1 AS SELECT * FROM plancache_memctl_tbl WHERE col1=$1;execute p1(1);
PREPARE
 col1 | col2 
------+------
    1 | test
(1 row)
gaussdb=# PREPARE p2 AS SELECT * FROM plancache_memctl_tbl WHERE col1=$1;execute p2(1);
PREPARE
 col1 | col2 
------+------
    1 | test
(1 row)
-- 创建大量计划缓存（根据业务实际进行创建，示例中不做展示）。
-- 查看内存视图。
gaussdb=# SELECT contextname, sum(totalsize)/1024/1024 sum, count(*) count FROM pv_session_memory_detail WHERE contextname ILIKE '%cachedplan%' GROUP BY contextname;
   contextname    |          sum          | count
------------------+-----------------------+-------
 CachedPlan       | .08398437500000000000 |     6
 CachedPlanQuery  | .02539062500000000000 |     6
 CachedPlanSource | .03515625000000000000 |     6
(3 rows)
 
-- 查看PREPARE语句。
gaussdb=# SELECT name,statement,size,is_deleted,valid FROM GS_ALL_PREPARED_STATEMENTS WHERE sessionid = pg_current_sessid() ORDER BY name;
 name |                            statement                            | size  | is_deleted | valid 
------+-----------------------------------------------------------------+-------+------------+-------
 p1   | prepare p1 as select * from plancache_memctl_tbl where col1=$1; |     0 | t          | f
 p2   | prepare p2 as select * from plancache_memctl_tbl where col1=$1; |     0 | t          | f
 p3   | prepare p3 as select * from plancache_memctl_tbl where col1=$1; |     0 | t          | f
 p4   | prepare p4 as select * from plancache_memctl_tbl where col1=$1; |     0 | t          | f
 p5   | prepare p5 as select * from plancache_memctl_tbl where col1=$1; | 15360 | f          | t
(5 rows)
gaussdb=# DROP TABLE plancache_memctl_tbl;
DROP TABLE
```
