统计信息
ANALYZE TABLE 用于更新表的统计信息,这些信息是查询优化器选择执行计划的关键依据。
核心作用
- 刷新索引的基数(cardinality):估算索引列中不同值的数量。
- 更新表的页数和行数估算:帮助优化器判断是走索引还是全表扫描。
- 提升复杂查询(多表 JOIN、范围查询)的计划质量:避免因过时统计导致索引失效或选错驱动表。
何时需要执行
- 大批量数据变更后( INSERT/UPDATE/DELETE 影响超过 10% 的行)。
- 表结构变更(如新增索引、分区)。
- 查询性能突然下降,怀疑统计信息陈旧。
使用示例
-- 分析单表
ANALYZE TABLE mydb.users;
-- 分析多个表
ANALYZE TABLE orders, products;
注意事项
- InnoDB 会在某些条件下(如表打开超过阈值)自动收集统计信息,但手动执行能更及时更新。
- 大表上执行
ANALYZE有一定 I/O 开销,建议在业务低峰期进行。 - 执行后优化器会使用新统计信息重新评估执行计划(可通过
EXPLAIN验证)。
分区表统计收集
execute dbms_stats.gather_table_stats(ownname => '{ownname}', tabname => '{tabname}',
partname => '{partname}', estimate_percent => null, method_opt => 'for all indexed columns',
cascade => true, degree => 45);
# estimate_percent => null: 表示Oracle将自动决定采样率。
# method_opt => 'for all indexed columns': 意味着对所有已索引的列进行直方图收集。
# cascade => true: 自动收集依赖于该表的所有相关对象(如索引、约束等)的统计信息。
# degree => 45: 收集统计信息时使用的进程数。
# 无分区的表则去掉`partname => '{partname}'`参数