1. 首页 > 国产数据库教程 > OceanBase教程 > 正文

OceanBase教程FG046-OceanBase统计信息与执行计划

本文详细介绍OceanBase数据库的统计信息与执行计划功能,帮助读者掌握OceanBase的统计信息管理和执行计划分析方法。风哥教程参考OceanBase官方文档OceanBase8统计信息、OceanBase8执行计划等内容。

统计信息与执行计划是数据库查询优化的重要组成部分,通过本文的学习,读者将掌握OceanBase的统计信息收集、执行计划生成、执行计划分析以及查询优化方法,提高数据库的查询性能。

本文将详细介绍OceanBase的统计信息管理、执行计划生成、执行计划分析以及实战案例。

目录大纲

Part01-基础概念与理论知识

1.1 统计信息概述

统计信息是数据库优化器用于生成执行计划的重要依据,它具有以下作用:

  • 估计基数:估计查询结果的行数
  • 估计成本:估计查询执行的成本
  • 选择执行计划:基于统计信息选择最优执行计划
  • 优化查询:通过统计信息优化查询语句

OceanBase的统计信息类型:

  • 表统计信息:表的行数、数据大小等
  • 列统计信息:列的分布、唯一值等
  • 索引统计信息:索引的 cardinality、高度等
  • 分区统计信息:分区的统计信息

1.2 执行计划概述

执行计划是数据库执行查询的具体步骤,它具有以下作用:

  • 展示执行步骤:展示查询的执行步骤和顺序
  • 显示操作类型:显示每个步骤的操作类型,如扫描、连接、排序等
  • 估计成本:显示每个步骤的估计成本和行数
  • 优化依据:作为查询优化的重要依据

OceanBase的执行计划类型:

  • EXPLAIN计划:通过EXPLAIN命令生成的执行计划
  • 实际执行计划:查询实际执行的计划
  • 可视化执行计划:通过工具可视化展示的执行计划

1.3 优化器原理

OceanBase的优化器原理:

  • 基于成本的优化:根据统计信息计算执行成本,选择成本最低的执行计划
  • 规则优化:基于规则对查询进行优化
  • 启发式优化:基于经验规则进行优化
  • 动态规划:通过动态规划算法选择最优执行计划

Part02-生产环境规划与建议

2.1 统计信息规划

统计信息规划:

  • 收集策略:制定统计信息收集策略,包括收集频率和方式
  • 存储策略:规划统计信息的存储方式和位置
  • 更新策略:制定统计信息更新策略,确保统计信息的准确性
  • ,风哥提示:。

  • 监控机制:建立统计信息监控机制,及时发现统计信息问题

2.2 执行计划优化建议

执行计划优化建议:

  • 使用索引:为查询条件创建合适的索引
  • 优化SQL语句:编写高效的SQL语句
  • 分析执行计划:定期分析执行计划,发现优化机会
  • 调整参数:根据执行计划调整相关参数
  • 使用绑定变量:使用绑定变量,减少硬解析

2.3 统计信息更新策略

统计信息更新策略:

  • 自动更新:启用自动统计信息更新
  • 手动更新:定期手动更新统计信息
  • 增量更新:对变更较大的表进行增量更新
  • 全量更新:定期对所有表进行全量更新
  • 监控更新:监控统计信息的更新情况

Part03-生产环境项目实施方案

3.1 统计信息收集实施

统计信息收集实施步骤:

    ,学习交流加群风哥微信: itpux-com。

  1. 配置统计信息收集
    • 启用自动统计信息收集
    • 设置统计信息收集参数
    • 配置收集频率
  2. 手动收集统计信息
    • 对特定表收集统计信息
    • 对特定列收集统计信息
    • 对索引收集统计信息
  3. 验证统计信息
    • 查看统计信息是否准确
    • 验证统计信息是否最新
    • 检查统计信息是否完整

3.2 执行计划分析实施

执行计划分析实施步骤:

  1. 生成执行计划
    • 使用EXPLAIN命令生成执行计划
    • 查看执行计划的详细信息
    • 分析执行计划的成本估算
  2. 分析执行计划
    • 识别执行计划中的瓶颈
    • 分析执行计划的操作类型
    • 评估执行计划的效率
  3. ,学习交流加群风哥QQ113257174。

  4. 优化执行计划
    • 根据执行计划调整SQL语句
    • 添加或修改索引
    • 调整相关参数

3.3 查询优化实施

查询优化实施步骤:

  1. 识别慢查询
    • 通过慢查询日志识别慢查询
    • 通过性能监控工具识别慢查询
    • 分析慢查询的执行计划
  2. 优化慢查询
    • 优化SQL语句结构
    • 添加合适的索引
    • 调整查询条件
  3. 验证优化效果
    • 测试优化后的查询性能
    • 对比优化前后的执行计划
    • 确认优化效果

Part04-生产案例与实战讲解

4.1 统计信息管理实战

,更多视频教程www.fgedu.net.cn。

统计信息管理实战示例:

— 1. 查看统计信息收集状态
SHOW VARIABLES LIKE ‘%statistics%’;
— 2. 启用自动统计信息收集
SET GLOBAL innodb_stats_auto_recalc = ON;
— 3. 手动收集表统计信息
ANALYZE TABLE fgedu_users;
— 4. 手动收集特定列统计信息
ANALYZE TABLE fgedu_users COLUMNS username, email;
— 5. 查看表统计信息
SHOW TABLE STATUS LIKE ‘fgedu_users’;
— 6. 查看列统计信息
SELECT * FROM information_schema.statistics WHERE table_schema = ‘fgedudb’ AND table_name = ‘fgedu_users’;
— 7. 查看索引统计信息
SHOW INDEX FROM fgedu_users;
— 8. 重置统计信息
FLUSH TABLES WITH READ LOCK;
UNLOCK TABLES;

— 查看统计信息收集状态
+———————————+——-+
| Variable_name | Value |
+———————————+——-+
| innodb_stats_auto_recalc | ON |
| innodb_stats_method | nulls_equal |
| innodb_stats_on_metadata | OFF |
| innodb_stats_persistent | ON |
| innodb_stats_persistent_sample_pages | 20 |
| innodb_stats_sample_pages | 8 |
| innodb_stats_transient_sample_pages | 8 |
+———————————+——-+

— 启用自动统计信息收集
Query OK, 0 rows affected (0.00 sec)

— 手动收集表统计信息
+—————+———+———-+———-+
| Table | Op | Msg_type | Msg_text |
+—————+———+———-+———-+,更多学习教程公众号风哥教程itpux_com。
| fgedudb.fgedu_users | analyze | status | OK |
+—————+———+———-+———-+

— 手动收集特定列统计信息
+—————+———+———-+———-+
| Table | Op | Msg_type | Msg_text |
+—————+———+———-+———-+
| fgedudb.fgedu_users | analyze | status | OK |
+—————+———+———-+———-+

— 查看表统计信息
+————+——–+———+————+——+—————-+————-+—————–+————–+———–+—————-+———————+————-+————+
| Name | Engine | Version | Row_format | Rows | Avg_row_length | Data_length | Max_data_length | Index_length | Data_free | Auto_increment | Create_time | Update_time | Check_time |
+————+——–+———+————+——+—————-+————-+—————–+————–+———–+—————-+———————+————-+————+
| fgedu_users | InnoDB | 10 | Dynamic | 1000 | 163 | 163840 | 0 | 32768 | 4194304 | 1001 | 2026-04-09 10:00:00 | NULL | NULL |
+————+——–+———+————+——+—————-+————-+—————–+————–+———–+—————-+———————+————-+————+

— 查看列统计信息
+—————+————–+————+————+————–+—————+——————+————–+———–+—————–+——————+————+
| TABLE_CATALOG | TABLE_SCHEMA | TABLE_NAME | NON_UNIQUE | INDEX_SCHEMA | INDEX_NAME | SEQ_IN_INDEX | COLUMN_NAME | COLLATION | CARDINALITY | SUB_PART | PACKED |
+—————+————–+————+————+————–+—————+——————+————–+———–+—————–+——————+————+
| def | fgedudb | fgedu_users | 0 | fgedudb | PRIMARY | 1 | id | A | 1000 | NULL | NULL |
| def | fgedudb | fgedu_users | 0 | fgedudb | idx_username | 1 | username | A | 1000 | NULL | NULL |
| def | fgedudb | fgedu_users | 1 | fgedudb | idx_email | 1 | email | A | 1000 | NULL | NULL |
+—————+————–+————+————+————–+—————+——————+————–+———–+—————–+——————+————+

— 查看索引统计信息
+————+————+———-+————–+————-+———–+————-+———-+——–+——+————+———+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+————+————+———-+————–+————-+———–+————-+———-+——–+——+————+———+,from DB视频:www.itpux.com。
| fgedu_users | 0 | PRIMARY | 1 | id | A | 1000 | NULL | NULL | | BTREE | |
| fgedu_users | 0 | idx_username | 1 | username | A | 1000 | NULL | NULL | | BTREE | |
| fgedu_users | 1 | idx_email | 1 | email | A | 1000 | NULL | NULL | | BTREE | |
+————+————+———-+————–+————-+———–+————-+———-+——–+——+————+———+

— 重置统计信息
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)

4.2 执行计划分析实战

执行计划分析实战示例:

— 1. 生成执行计划
EXPLAIN SELECT * FROM fgedu_users WHERE id = 1;
— 2. 生成详细执行计划
EXPLAIN EXTENDED SELECT * FROM fgedu_users WHERE id = 1;
— 3. 生成JSON格式执行计划
EXPLAIN FORMAT=JSON SELECT * FROM fgedu_users WHERE id = 1;
— 4. 分析复杂查询执行计划
EXPLAIN SELECT u.id, u.username, o.order_id, o.order_amount
FROM fgedu_users u
INNER JOIN fgedu_orders o ON u.id = o.user_id
WHERE u.id > 1;
— 5. 分析带排序的查询执行计划
EXPLAIN SELECT * FROM fgedu_users ORDER BY username DESC;
— 6. 分析带聚合的查询执行计划
EXPLAIN SELECT user_id, SUM(order_amount) FROM fgedu_orders GROUP BY user_id;
— 7. 分析子查询执行计划
EXPLAIN SELECT * FROM fgedu_users WHERE id IN (SELECT user_id FROM fgedu_orders WHERE order_amount > 100);

— 生成执行计划
+—-+————-+————+————+——-+—————+———+———+——-+——+———-+————-+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+—-+————-+————+————+——-+—————+———+———+——-+——+———-+————-+
| 1 | SIMPLE | fgedu_users | NULL | const | PRIMARY | PRIMARY | 4 | const | 1 | 100.00 | NULL |
+—-+————-+————+————+——-+—————+———+———+——-+——+———-+————-+

— 生成详细执行计划
+—-+————-+————+————+——-+—————+———+———+——-+——+———-+————-+————————–+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | Extra |
+—-+————-+————+————+——-+—————+———+———+——-+——+———-+————-+————————–+
| 1 | SIMPLE | fgedu_users | NULL | const | PRIMARY | PRIMARY | 4 | const | 1 | 100.00 | NULL | Using index condition |
+—-+————-+————+————+——-+—————+———+———+——-+——+———-+————-+————————–+

— 生成JSON格式执行计划
{
“query_block”: {
“select_id”: 1,
“cost_info”: {
“query_cost”: “1.00”
},
“table”: {
“table_name”: “fgedu_users”,
“access_type”: “const”,
“possible_keys”: [
“PRIMARY”
],
“key”: “PRIMARY”,
“used_key_parts”: [
“id”
],
“key_length”: “4”,
“ref”: [
“const”
],
“rows_examined_per_scan”: 1,
“rows_produced_per_join”: 1,
“filtered”: “100.00”,
“cost_info”: {
“read_cost”: “0.00”,
“eval_cost”: “0.00”,
“prefix_cost”: “0.00”,
“data_read_per_join”: “163”
},
“used_columns”: [
“id”,
“username”,
“email”,
“balance”
]
}
}
}

— 分析复杂查询执行计划
+—-+————-+——-+————+——–+—————+———+———+—————+——+———-+————-+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+—-+————-+——-+————+——–+—————+———+———+—————+——+———-+————-+
| 1 | SIMPLE | u | NULL | range | PRIMARY | PRIMARY | 4 | NULL | 999 | 100.00 | Using where |
| 1 | SIMPLE | o | NULL | ref | idx_user_id | idx_user_id | 4 | fgedudb.u.id | 5 | 100.00 | NULL |
+—-+————-+——-+————+——–+—————+———+———+—————+——+———-+————-+

— 分析带排序的查询执行计划
+—-+————-+————+————+——-+—————+———-+———+——-+——+———-+—————-+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+—-+————-+————+————+——-+—————+———-+———+——-+——+———-+—————-+
| 1 | SIMPLE | fgedu_users | NULL | index | NULL | idx_username | 202 | NULL | 1000 | 100.00 | Using index |
+—-+————-+————+————+——-+—————+———-+———+——-+——+———-+—————-+

— 分析带聚合的查询执行计划
+—-+————-+————+————+——-+—————+———-+———+——-+——+———-+—————-+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+—-+————-+————+————+——-+—————+———-+———+——-+——+———-+—————-+
| 1 | SIMPLE | fgedu_orders | NULL | index | idx_user_id | idx_user_id | 4 | NULL | 5000 | 100.00 | Using index |
+—-+————-+————+————+——-+—————+———-+———+——-+——+———-+—————-+

— 分析子查询执行计划
+—-+————-+————+————+——-+—————+———-+———+——-+——+———-+————————+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+—-+————-+————+————+——-+—————+———-+———+——-+——+———-+————————+
| 1 | SIMPLE | fgedu_users | NULL | range | PRIMARY | PRIMARY | 4 | NULL | 999 | 100.00 | Using where; Using index |
| 1 | SIMPLE | fgedu_orders | NULL | ref | idx_user_id | idx_user_id | 4 | fgedudb.fgedu_users.id | 5 | 33.33 | Using where; Using index |
+—-+————-+————+————+——-+—————+———-+———+——-+——+———-+————————+

4.3 查询优化实战

查询优化实战示例:

— 1. 优化全表扫描
— 原查询
EXPLAIN SELECT * FROM fgedu_orders WHERE user_id = 1;
— 添加索引
CREATE INDEX idx_user_id ON fgedu_orders(user_id);
— 优化后查询
EXPLAIN SELECT * FROM fgedu_orders WHERE user_id = 1;
— 2. 优化排序操作
— 原查询
EXPLAIN SELECT * FROM fgedu_users ORDER BY created_at;
— 添加索引
CREATE INDEX idx_created_at ON fgedu_users(created_at);
— 优化后查询
EXPLAIN SELECT * FROM fgedu_users ORDER BY created_at;
— 3. 优化连接查询
— 原查询
EXPLAIN SELECT u.id, u.username, o.order_id, o.order_amount
FROM fgedu_users u
INNER JOIN fgedu_orders o ON u.id = o.user_id
WHERE u.id > 1;
— 添加索引
CREATE INDEX idx_user_id ON fgedu_orders(user_id);
— 优化后查询
EXPLAIN SELECT u.id, u.username, o.order_id, o.order_amount
FROM fgedu_users u
INNER JOIN fgedu_orders o ON u.id = o.user_id
WHERE u.id > 1;
— 4. 优化聚合查询
— 原查询
EXPLAIN SELECT user_id, SUM(order_amount) FROM fgedu_orders GROUP BY user_id;
— 添加索引
CREATE INDEX idx_user_id ON fgedu_orders(user_id);
— 优化后查询
EXPLAIN SELECT user_id, SUM(order_amount) FROM fgedu_orders GROUP BY user_id;
— 5. 优化子查询
— 原查询
EXPLAIN SELECT * FROM fgedu_users WHERE id IN (SELECT user_id FROM fgedu_orders WHERE order_amount > 100);
— 优化为连接查询
EXPLAIN SELECT u.* FROM fgedu_users u
INNER JOIN fgedu_orders o ON u.id = o.user_id
WHERE o.order_amount > 100;

— 优化全表扫描
— 原查询
+—-+————-+————+————+——+—————+——+———+——+——+———-+————-+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+—-+————-+————+————+——+—————+——+———+——+——+———-+————-+
| 1 | SIMPLE | fgedu_orders | NULL | ALL | NULL | NULL | NULL | NULL | 5000 | 10.00 | Using where |
+—-+————-+————+————+——+—————+——+———+——+——+———-+————-+

— 添加索引
Query OK, 0 rows affected (0.01 sec)

— 优化后查询
+—-+————-+————+————+——+—————+———-+———+——-+——+———-+————-+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+—-+————-+————+————+——+—————+———-+———+——-+——+———-+————-+
| 1 | SIMPLE | fgedu_orders | NULL | ref | idx_user_id | idx_user_id | 4 | const | 5 | 100.00 | NULL |
+—-+————-+————+————+——+—————+———-+———+——-+——+———-+————-+

— 优化排序操作
— 原查询
+—-+————-+————+————+——+—————+——+———+——+——+———-+—————-+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+—-+————-+————+————+——+—————+——+———+——+——+———-+—————-+
| 1 | SIMPLE | fgedu_users | NULL | ALL | NULL | NULL | NULL | NULL | 1000 | 100.00 | Using filesort |
+—-+————-+————+————+——+—————+——+———+——+——+———-+—————-+

— 添加索引
Query OK, 0 rows affected (0.01 sec)

— 优化后查询
+—-+————-+————+————+——-+—————+————–+———+——-+——+———-+————-+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+—-+————-+————+————+——-+—————+————–+———+——-+——+———-+————-+
| 1 | SIMPLE | fgedu_users | NULL | index | NULL | idx_created_at | 5 | NULL | 1000 | 100.00 | NULL |
+—-+————-+————+————+——-+—————+————–+———+——-+——+———-+————-+

— 优化连接查询
— 原查询
+—-+————-+——-+————+——–+—————+———+———+—————+——+———-+————-+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+—-+————-+——-+————+——–+—————+———+———+—————+——+———-+————-+
| 1 | SIMPLE | u | NULL | range | PRIMARY | PRIMARY | 4 | NULL | 999 | 100.00 | Using where |
| 1 | SIMPLE | o | NULL | ALL | NULL | NULL | NULL | NULL | 5000 | 10.00 | Using where; Using join buffer (Block Nested Loop) |
+—-+————-+——-+————+——–+—————+———+———+—————+——+———-+————-+

— 添加索引
Query OK, 0 rows affected (0.01 sec)

— 优化后查询
+—-+————-+——-+————+——–+—————+———-+———+—————+——+———-+————-+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+—-+————-+——-+————+——–+—————+———-+———+—————+——+———-+————-+
| 1 | SIMPLE | u | NULL | range | PRIMARY | PRIMARY | 4 | NULL | 999 | 100.00 | Using where |
| 1 | SIMPLE | o | NULL | ref | idx_user_id | idx_user_id | 4 | fgedudb.u.id | 5 | 100.00 | NULL |
+—-+————-+——-+————+——–+—————+———-+———+—————+——+———-+————-+

— 优化聚合查询
— 原查询
+—-+————-+————+————+——+—————+——+———+——+——+———-+—————-+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+—-+————-+————+————+——+—————+——+———+——+——+———-+—————-+
| 1 | SIMPLE | fgedu_orders | NULL | ALL | NULL | NULL | NULL | NULL | 5000 | 100.00 | Using temporary |
+—-+————-+————+————+——+—————+——+———+——+——+———-+—————-+

— 添加索引
Query OK, 0 rows affected (0.01 sec)

— 优化后查询
+—-+————-+————+————+——-+—————+———-+———+——-+——+———-+—————-+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+—-+————-+————+————+——-+—————+———-+———+——-+——+———-+—————-+
| 1 | SIMPLE | fgedu_orders | NULL | index | idx_user_id | idx_user_id | 4 | NULL | 5000 | 100.00 | Using index |
+—-+————-+————+————+——-+—————+———-+———+——-+——+———-+—————-+

— 优化子查询
— 原查询
+—-+————-+————+————+——-+—————+———-+———+——-+——+———-+————————+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+—-+————-+————+————+——-+—————+———-+———+——-+——+———-+————————+
| 1 | SIMPLE | fgedu_users | NULL | range | PRIMARY | PRIMARY | 4 | NULL | 999 | 100.00 | Using where; Using index |
| 1 | SIMPLE | fgedu_orders | NULL | ref | idx_user_id | idx_user_id | 4 | fgedudb.fgedu_users.id | 5 | 33.33 | Using where; Using index |
+—-+————-+————+————+——-+—————+———-+———+——-+——+———-+————————+

— 优化为连接查询
+—-+————-+——-+————+——-+—————+———-+———+—————+——+———-+————————+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+—-+————-+——-+————+——-+—————+———-+———+—————+——+———-+————————+
| 1 | SIMPLE | o | NULL | range | idx_user_id | idx_user_id | 4 | NULL | 1667 | 100.00 | Using where; Using index |
| 1 | SIMPLE | u | NULL | eq_ref | PRIMARY | PRIMARY | 4 | fgedudb.o.user_id | 1 | 100.00 | Using index |
+—-+————-+——-+————+——-+—————+———-+———+—————+——+———-+————————+

Part05-风哥经验总结与分享

5.1 统计信息管理最佳实践

统计信息管理最佳实践:

  • 定期收集:定期收集统计信息,确保统计信息的准确性
  • 自动更新:启用自动统计信息更新,减少手动操作
  • 监控统计信息:监控统计信息的状态,及时发现问题
  • 合理设置参数:根据业务特点设置合适的统计信息收集参数
  • 分析统计信息:定期分析统计信息,发现优化机会

5.2 执行计划优化最佳实践

执行计划优化最佳实践:

  • 分析执行计划:定期分析执行计划,发现性能瓶颈
  • 使用索引:为查询条件创建合适的索引
  • 优化SQL语句:编写高效的SQL语句
  • 调整参数:根据执行计划调整相关参数
  • 监控执行计划:监控执行计划的变化,及时发现问题

本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.html

联系我们

在线咨询:点击这里给我发消息

微信号:itpux-com

工作日:9:30-18:30,节假日休息