一、SQL执行计划缓存是什么

数据库处理SQL语句时,需要经历解析、优化、执行三个阶段。其中优化阶段生成的执行计划直接影响查询性能。想象一下,如果每次执行相同SQL都要重新生成执行计划,就像每次开车去同一个地方都要重新规划路线一样浪费资源。

执行计划缓存就是将优化后的执行计划保存起来,当相同SQL再次执行时直接复用。OceanBase作为分布式数据库,其执行计划缓存机制尤为关键,能显著降低CPU消耗和响应时间。

举个生活中的例子:你去常去的餐馆点菜,服务员不用每次都问你的口味偏好,直接按老规矩上菜,这就是执行计划缓存的现实映射。

二、OceanBase执行计划缓存工作原理

OceanBase的执行计划缓存采用基于哈希的存储结构,核心流程如下:

  1. SQL文本经过规范化处理后生成唯一的SQL_ID
  2. 以SQL_ID为键在缓存中查找
  3. 命中则直接使用缓存计划
  4. 未命中则进行硬解析并缓存新计划

技术栈:OceanBase 3.x版本

-- 查看当前执行计划缓存状态(OceanBase特有语法)
SELECT /*+ READ_CONSISTENCY(WEAK) */ 
       tenant_id,
       svr_ip,
       svr_port,
       plan_cache_size,
       plan_cache_evict
FROM __all_virtual_plan_cache_stat
WHERE tenant_id = 1001;

/*
注释说明:
tenant_id: 租户ID
svr_ip/svr_port: 服务器地址
plan_cache_size: 缓存大小(KB)
plan_cache_evict: 淘汰的缓存数量
*/

缓存淘汰策略采用改进的LRU算法,考虑因素包括:

  • 执行频率
  • 内存压力
  • SQL复杂度
  • 计划有效性

三、关键参数调优指南

OceanBase提供了丰富的参数控制执行计划缓存行为,以下是核心参数:

1. 基础容量参数

-- 设置执行计划缓存容量(单位:MB)
ALTER SYSTEM SET _ob_plan_cache_size = '512M';

-- 设置单个SQL计划缓存上限(单位:KB)
ALTER SYSTEM SET _ob_plan_cache_max_plan_size = '256K';

2. 淘汰策略参数

-- 设置LRU淘汰阈值(百分比)
ALTER SYSTEM SET _ob_plan_cache_evict_high_percentage = 90;

-- 设置淘汰检查间隔(单位:秒)
ALTER SYSTEM SET _ob_plan_cache_evict_interval = 60;

3. 特殊场景参数

-- 是否缓存INSERT/UPDATE/DELETE计划
ALTER SYSTEM SET _ob_plan_cache_store_dml = 'TRUE';

-- 绑定变量处理模式
ALTER SYSTEM SET _ob_plan_cache_handle_batch = 'EXTEND';

实际案例:某电商平台大促期间出现性能波动,通过以下调整解决:

-- 临时扩容计划缓存
ALTER SYSTEM SET _ob_plan_cache_size = '2G';

-- 提高淘汰阈值减少频繁淘汰
ALTER SYSTEM SET _ob_plan_cache_evict_high_percentage = 95;

-- 增加检查间隔降低开销
ALTER SYSTEM SET _ob_plan_cache_evict_interval = 120;

四、实战问题排查技巧

当执行计划缓存出现问题时,可以按以下步骤排查:

  1. 确认缓存命中率
SELECT /*+ READ_CONSISTENCY(WEAK) */
       (hit_count/(hit_count+miss_count))*100 as hit_ratio
FROM __all_virtual_plan_cache_stat
WHERE tenant_id = 1001;
  1. 分析低效SQL
-- 查找未使用绑定变量的SQL
SELECT /*+ READ_CONSISTENCY(WEAK) */
       sql_id, 
       query_sql
FROM __all_virtual_sql_audit
WHERE tenant_id = 1001
AND query_sql LIKE '%WHERE id=%'
ORDER BY elapsed_time DESC
LIMIT 10;
  1. 强制刷新问题SQL缓存
-- 清除特定SQL的缓存计划
ALTER SYSTEM FLUSH PLAN CACHE sql_id='B7A8D3C1E5F2A9D0';

常见问题场景:

  • 绑定变量使用不当导致缓存膨胀
  • 统计信息过时产生低效计划
  • 参数设置不合理导致频繁淘汰

五、最佳实践建议

根据多年优化经验,总结以下建议:

  1. 合理设置缓存大小

    • OLTP系统:总内存的10-20%
    • OLAP系统:总内存的5-10%
  2. 规范SQL编写

    • 统一使用绑定变量
    • 避免SQL文本差异(如多余空格)
  3. 监控策略

    -- 创建定期监控任务
    CREATE TABLE plan_cache_monitor (
      sample_time TIMESTAMP,
      hit_ratio DECIMAL(5,2),
      cache_size BIGINT
    );
    
  4. 特殊处理

    • 对关键SQL使用HINT固定执行计划
    • 定期刷新统计信息

六、技术对比与选型思考

与MySQL的查询缓存不同,OceanBase执行计划缓存:

  • 只缓存执行计划而非结果
  • 支持分布式环境同步
  • 提供更细粒度的控制

优势:

  • 降低CPU消耗达30-50%
  • 减少响应时间波动
  • 支持多租户隔离

局限:

  • 内存占用需要权衡
  • 参数调优需要经验
  • 分布式一致性开销

七、总结与展望

执行计划缓存是OceanBase性能优化的核心手段之一。合理使用可以显著提升系统吞吐量,但需要结合业务特点进行精细调优。随着OceanBase持续演进,未来可能在以下方向改进:

  1. 智能自适应缓存大小调整
  2. 基于机器学习的计划预测
  3. 更细粒度的缓存分区策略

记住:没有放之四海皆准的最优配置,只有最适合业务场景的参数组合。建议从默认配置开始,通过持续监控逐步优化。