OCP实验 | 03-SQL优化

OceanBase SQL 优化考试笔记

4、SQL 优化

4.1 统计信息默认选择率

核心概念

OceanBase 优化器两种估行方式

  • 基于选择率的行数估计
  • 基于存储层的行数估计

选择率

  • 选择率越低越好,数据唯一性越高越好
  • 选择率 = 查询返回行数 / 表总行数
  • 计算结果需要 ×100

NDV(Number of Distinct Values)

  • 某一列中不同值的数量
  • 用于优化器生成执行计划
选择率计算
sql 复制代码
-- 实际行数
SELECT COUNT(*) FROM t1 WHERE c1 = 10;  

-- 实际选择率
(查询返回行数) / (表总行数) × 100

预估选择率

  • EST.ROWS / table_rows
  • EXPLAIN EXTENDED 中的 OUTPUT_ROWS / table_rows
考试关键点
  • 无统计信息时,OB 默认 NDV=100
  • 等值查询默认选择率 = 0.01(1%)
  • 思考:3 条 SQL 预估行数 = 100,就是因为默认 NDV=100

4.2 统计信息采集相关表

自动采集(每日合并)
sql 复制代码
__all_virtual_meta_table
__all_virtual_column_statistic
手工收集(集群级 / MySQL 租户)
sql 复制代码
__all_virtual_table_stat_v2   / __all_table_stat_v2
__all_virtual_column_stat_v2  / __all_column_stat_v2
__all_virtual_histogram_stat_v2 / __all_histogram_stat_v2
手工采集(Oracle 租户级)
sql 复制代码
all_tab_statistics
all_tab_col_statistics
all_tab_histograms
连接/进程相关
sql 复制代码
oceanbase.__all_virtual_processlist  -- 集群租户
sys.all_virtual_processlist          -- Oracle sys 租户

4.3 SQL 优化(实操重点)

考试要求
  • 给定 SQL,从 9s → <1s
  • 必须查 plan_cache_plan_explain 查看真实执行计划
  • 直接 EXPLAIN 不得分
查看真实执行计划(必背)
sql 复制代码
SELECT 
  PLAN_DEPTH,PLAN_LINE_ID,OPERATOR,NAME,ROWS,COST 
FROM gv$plan_cache_plan_explain 
WHERE TENANT_ID=1002 
  AND ip='10.186.65.12' 
  AND port=2882 
  AND PLAN_ID=648 
ORDER BY PLAN_LINE_ID;
优化手段
  1. 调整驱动表 / JOIN 顺序
  2. 绑定 OUTLINE(固定执行计划)
  3. 添加 HINT
sql 复制代码
/*+ leading(a) use_nl(a,b,f) */
创建 Outline(固定执行计划)
sql 复制代码
CREATE OUTLINE outline2 
ON 'ED570339F2C856BA96008A29EDF04C74' 
USING HINT /*+ index(tbl1 idx_col2)*/;
查看 SQL 审计
sql 复制代码
gv$sql_audit

4.4 合并(Major Freeze)

合并操作命令
sql 复制代码
-- 暂停合并
ALTER SYSTEM SUSPEND MERGE;

-- 恢复合并
ALTER SYSTEM RESUME MERGE;

-- 发起一次合并(重要)
ALTER SYSTEM MAJOR FREEZE;
查询字段统计信息(多表关联)

考试场景 :做一次合并,查询某表 c2 字段统计信息

返回:table_name、column_name、num_distinct、min_value、max_value

sql 复制代码
USE oceanbase;

SELECT 
  t1.table_name,
  t2.column_name,
  t3.num_distinct,
  t3.min_value,
  t3.max_value
FROM __all_virtual_table t1
INNER JOIN __all_virtual_column t2 
  ON t1.tenant_id=t2.tenant_id AND t1.table_id=t2.table_id
INNER JOIN __all_virtual_column_statistic t3 
  ON t2.tenant_id=t3.tenant_id 
  AND t2.table_id=t3.table_id 
  AND t2.column_id=t3.column_id
WHERE t1.tenant_id=1003
  AND t1.table_name='goods_info'
  AND t2.column_name='goods_name';

4.5 收集统计信息

两种收集方式
sql 复制代码
ANALYZE TABLE
CALL dbms_stats.gather_table_stats
收集指定表/列统计信息
sql 复制代码
-- 收集指定列
CALL dbms_stats.gather_table_stats('tpcc','chap41', method_opt=>'for columns c3 size auto');

-- 收集所有列
CALL DBMS_STATS.GATHER_TABLE_STATS (
  'tpcc', 'chap41', 
  method_opt=>'FOR ALL COLUMNS SIZE AUTO', 
  granularity=>'ALL', 
  degree=>4
);
sql 复制代码
-- 收集直方图
ANALYZE TABLE tbl1 UPDATE HISTOGRAM ON a,b,c,d WITH 30 BUCKETS;

ANALYZE TABLE t1 UPDATE HISTOGRAM ON c1 WITH 30 BUCKETS;
查询统计信息
sql 复制代码
-- 查询 table_id
SELECT * FROM gv$table WHERE tenant_id=1003 AND table_name='t_user_transaction'\G;

-- 查询列级统计信息
SELECT * FROM __all_virtual_column_stat_v2 WHERE table_id='1101710651081564'\G

相关推荐
流星白龙39 分钟前
【MySQL高阶】13.其他存储引擎
android·数据库·mysql
薛定谔的悦41 分钟前
光伏-储能-负荷联合预测:给 EMS 装上“预知能力“
java·数据库·人工智能·python·储能
阿演43 分钟前
DataDjinn v0.1.6 更新:增加在线更新功能,Redis 数据源支持,表格预览和连接体验继续增强
数据库·redis·缓存·数据库连接工具
数据库小学妹44 分钟前
InnoDB内存架构解密:Buffer Pool与性能优化实战
数据库·经验分享·sql·性能优化·架构
Lyyaoo.1 小时前
【MySQL】SQL优化
android·sql·mysql
AI人工智能+电脑小能手1 小时前
【大白话说Java面试题 第89题】【Mysql篇】第19题:Hash 索引和 B+ 树索引的区别?它们在使用方面的区别?
java·数据库·mysql·面试·哈希算法
一只fish1 小时前
Oracle官方文档翻译《Database Concepts 26ai》第17章-内存架构
数据库·oracle
比企谷八幡1 小时前
一张表在磁盘上长什么样:Heap File 入门
数据库·oracle
流星白龙1 小时前
【MySQL高阶】11.InnoDB存储引擎
数据库·mysql
wangbing11252 小时前
SQL Server2008 R2版自动备份问题
数据库