OceanBase SQL引擎高级技术学习笔记:从“点餐”到“上菜”的数据库之旅
数据库的SQL引擎可以说是数据库原理的核心部分之一,但是对于大多数数据库初学者来说,学习起来枯燥乏味,因此本人将OceanBase SQL引擎的核心流程类比为餐厅运作,希望帮助你轻松理解技术细节。
一、SQL请求执行流程:餐厅点餐全流程
想象你去餐厅吃饭的过程:
- 点餐(SQL请求):你告诉服务员"我要鱼香肉丝和米饭"
- 厨师理解菜单(词法/语法解析):厨师把"鱼香肉丝=猪肉+木耳+胡萝卜+辣椒酱"拆解成食材清单
- 确认食材(语义解析):厨师检查冰箱是否有这些食材
- 优化做法(逻辑改写):厨师发现可以用预制酱料节省时间
- 制定烹饪计划(优化器):决定先炒肉还是先炒菜
- 准备厨具(代码生成器):拿出炒锅和刀具
- 烹饪(执行器):按步骤制作菜品
- 上菜(返回结果):服务员端上美味菜肴
二、核心模块详解
1. 快速参数化:餐厅的"常客菜单"
- 把具体值变成通用参数:
-- 原始SQL SELECT * FROM menu WHERE dish_id = 5 AND category = '川菜' -- 参数化后 SELECT * FROM menu WHERE dish_id = @1 AND category = @2
- 参数数组:[5, ‘川菜’]
- 好处:不同顾客点同一类菜(只是具体菜品不同)可以用相同烹饪流程
2. 执行计划缓存:厨师的"拿手菜记忆"
- 第一次做菜:需要研究菜谱(硬解析,耗时10-100ms)
- 后续再做:直接按记忆操作(软解析,<1ms)
- 查看缓存:
-- 查看计划缓存中的SQL SELECT * FROM v$plan_cache_plan_stat WHERE statement LIKE 'SELECT%menu%'; -- 查看具体执行计划 SELECT * FROM v$plan_cache_plan_explain WHERE tenant_id=1001 AND plan_id=7;
3. 查询改写:优化烹饪流程
子查询转连接(避免重复劳动)
-- 原始(厨师每做一道菜都要查一次库存)
SELECT * FROM orders
WHERE dish_id IN (SELECT id FROM menu WHERE price > 50)
-- 改写后(一次性获取所有高端菜品)
SELECT orders.*
FROM orders JOIN menu ON orders.dish_id = menu.id
WHERE menu.price > 50
或展开(Or-Expansion):分流处理
-- 原始(大杂烩做法)
SELECT * FROM menu
WHERE category='川菜' OR price < 30
-- 改写后(分开两个锅同时做)(使用LNNVL排除已覆盖条件)
SELECT * FROM menu WHERE category='川菜'
UNION ALL
SELECT * FROM menu
WHERE price < 30 AND LNNVL(category='川菜')
三、DML语句处理:厨房操作指南
1. INSERT:新菜上架
EXPLAIN INSERT INTO menu(dish_id, name) VALUES (100, '麻婆豆腐');
-- 执行计划:
-- | 0 | INSERT | | 1行 |
-- | 1 | EXPRESSION | | 1行 |
就像往菜单本上手写新菜,不需要检查现有菜品
2. UPDATE:修改菜品
EXPLAIN UPDATE menu SET price=38 WHERE dish_id=100;
-- 执行计划:
-- | 0 | UPDATE | | 1行 |
-- | 1 | TABLE SCAN | menu | 1行 |
类似修改菜单价格,需要先找到对应菜品
3. DELETE:下架菜品
EXPLAIN DELETE FROM menu WHERE dish_id=100;
-- 执行计划:
-- | 0 | DELETE | | 1行 |
-- | 1 | TABLE SCAN | menu | 1行 |
从菜单本划掉菜品,需先定位
四、执行计划分析:查看"烹饪方案"
1. 基础查看(EXPLAIN)
EXPLAIN SELECT * FROM menu WHERE category='川菜';
-- 输出:
-- | ID | OPERATOR | NAME | EST.ROWS | COST |
-- | 0 | TABLE SCAN| menu | 20 | 45 |
2. 实时执行计划(查看实际使用的方案)
-- 1. 查找plan_id
SELECT plan_id FROM v$plan_cache_plan_stat
WHERE statement LIKE 'SELECT%menu%';
-- 2. 查看实时计划
SELECT * FROM v$plan_cache_plan_explain
WHERE tenant_id=1001 AND plan_id=123;
五、执行计划缓存管理:厨房记忆优化
自动淘汰机制(类比餐厅菜单更新)
手动刷新缓存
-- 清空本机所有计划缓存
ALTER SYSTEM FLUSH PLAN CACHE;
-- 清空特定租户的全局缓存
ALTER SYSTEM FLUSH PLAN CACHE TENANT='food_app' GLOBAL;
六、生活场景类比总结
技术概念 | 生活类比 | 关键要点 |
---|---|---|
快速参数化 | 常客的"老规矩"订单 | 鱼香肉丝=@1,宫保鸡丁=@2 |
执行计划缓存 | 厨师的拿手菜肌肉记忆 | 第一次慢,后续秒出餐 |
查询改写 | 优化烹饪流程 | 分开处理川菜和粤菜订单 |
执行计划 | 菜品的标准操作流程卡 | 记录烹饪步骤和时间预估 |
DML操作 | 菜单更新操作 | 新增/修改/下架菜品 |
计划缓存淘汰 | 淘汰冷门菜品的记忆 | 三个月没人点的菜移出厨师记忆 |
黄金法则:数据库就像高级餐厅,优化器是主厨,执行计划是食谱,缓存是厨师的肌肉记忆。好的"餐厅"要能快速理解订单(解析),优化烹饪流程(改写),记住热门菜品做法(缓存),并定期更新菜单(淘汰机制)。