存在一个表数据30w左右,没有通过ANALYZE TABLE xxxx COMPUTE STATISTICS FOR ALL COLUMNS SIZE AUTO;后表的查询返回是30s左右的结果返回,经过ANALYZE TABLE xxxx COMPUTE STATISTICS FOR ALL COLUMNS SIZE AUTO;语句统计分析后优化到1s返回,但是重启OceanBase服务器后再去查询这个表,速度又回到没加ANALYZE 之前的30s的状态,我查看了https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000001502819这个文章
重启之后执行计划需要重新解析
根据文档库中的信息,可以为您提供以下解答:
问题分析
-
统计信息的作用
OceanBase 数据库优化器依赖统计信息生成最优的执行计划。通过ANALYZE TABLE
或DBMS_STATS
收集统计信息后,优化器能够更准确地估算查询成本,从而选择更优的执行计划(如走索引而非全表扫描)。这正是您在执行ANALYZE TABLE
后查询性能显著提升的原因。 -
重启后性能下降的原因
根据文档片段 6 和 7 的描述,OceanBase 数据库会在本地维护一个统计信息缓存以加速优化器对统计信息的访问。然而,这种缓存是内存中的数据结构,在数据库重启后会被清空。因此,即使统计信息本身存储在内部表中并未丢失,但优化器需要重新加载这些统计信息到缓存中才能高效使用。
解决方案
方法 1:手动触发统计信息加载
可以通过以下方式手动触发统计信息加载:
-
硬解析 SQL
在重启 OceanBase 数据库后,首次执行相关 SQL 查询时会触发硬解析,此时优化器会从内部表中读取统计信息并加载到缓存中。虽然这种方式不需要额外操作,但可能会导致首次查询性能较差。 -
强制刷新统计信息缓存
使用DBMS_STATS.FLUSH_DATABASE_MONITORING_INFO
或类似功能(具体取决于版本支持情况)来手动刷新统计信息缓存。这种方法可以确保统计信息在重启后立即可用。
方法 2:配置自动统计信息收集
根据文档片段 5 的描述,OceanBase 数据库支持通过 MAINTENANCE WINDOW
自动收集统计信息。您可以检查并调整以下配置:
-
启用自动统计信息收集
确保MAINTENANCE WINDOW
功能已启用,并合理设置每日自动统计信息收集的时间窗口(如周一至周五 22:00 开始,最大收集时长 4 小时)。这样可以在数据库重启后定期更新统计信息。 -
检查统计信息收集状态
使用以下 SQL 查询统计信息收集任务的状态:SELECT * FROM GV$OB_STATISTICS_TASK_STATUS;
如果发现某些表的统计信息收集失败,需及时诊断和修复。
方法 3:持久化统计信息
虽然统计信息本身已经持久化存储在内部表中,但为了进一步减少重启后的性能波动,可以考虑以下措施:
-
绑定执行计划
使用DBMS_SPM
或其他计划绑定工具将优化的执行计划固定下来。这样即使统计信息未完全加载,优化器也会优先使用绑定的计划,避免性能大幅下降。 -
定期导出导入统计信息
使用DBMS_STATS.IMPORT_STATISTICS
和DBMS_STATS.EXPORT_STATISTICS
导出并导入统计信息。这种方法适合在特定场景下快速恢复统计信息。
综合建议
-
短期解决方案
- 在每次重启 OceanBase 数据库后,手动执行一次
ANALYZE TABLE
或调用DBMS_STATS
收集统计信息。 - 或者通过硬解析 SQL 查询的方式让优化器重新加载统计信息。
- 在每次重启 OceanBase 数据库后,手动执行一次
-
长期解决方案
- 配置并启用
MAINTENANCE WINDOW
自动统计信息收集功能。 - 使用计划绑定工具固定优化的执行计划。
- 定期检查统计信息收集任务的状态,确保所有关键表的统计信息始终处于最新状态。
- 配置并启用
参考文档
-
统计信息收集与缓存机制
文档名称:《OceanBase 数据库性能的影响因素 → 合并与统计信息收集 → 统计信息收集》
段落标题:统计信息以普通数据的形式存储在内部表中,并且会在本地维护一个统计信息缓存。 -
自动统计信息收集
文档名称:《OceanBase 数据库优化器 → 统计信息收集监控诊断功能》
段落标题:V4.2.0 版本开始支持统计信息收集监控诊断功能。
如果您仍有疑问,建议联系 OceanBase 的技术支持团队获取进一步帮助。
更多信息请查看:
重启后,该sql是一直都是30s执行时间么。可能是第一次执行slq硬解析慢导致。
obd安装使用obdiag 收集下sql信息
SQL性能问题, 此处env中的trace_id对应gv$ob_sql_audit的trace_id
obdiag gather scene run --scene=observer.perf_sql --env “{db_connect=’-hxx -Pxx -uxx -pxx -Dxx’, trace_id=‘xx’}”
这个是一个比较长久的方案
需要开启自动统计信息功能