OceanBase教程FG065-OceanBase批量更新删除优化实战
本文档风哥主要介绍OceanBase数据库批量更新删除优化相关知识,包括OceanBase批量更新删除概念、OceanBase更新删除机制、OceanBase性能影响因素、OceanBase批量大小规划、OceanBase批量更新、OceanBase批量删除、OceanBase REPLACE INTO等内容,风哥教程参考OceanBase官方文档性能优化、DML优化等内容编写,适合DBA人员在学习和测试中使用,如果要应用于生产环境则需要自行确认。
Part01-基础概念与理论知识
1.1 OceanBase批量更新删除概念
批量更新删除是指一次性处理多条记录的UPDATE或DELETE操作,相比单条操作可以显著提升性能。更多视频教程www.fgedu.net.cn
- 批量UPDATE:UPDATE … WHERE id IN (…)
- 批量DELETE:DELETE FROM … WHERE id IN (…)
- REPLACE INTO:REPLACE INTO … VALUES (…)
- INSERT ON DUPLICATE KEY UPDATE:插入或更新
- 多表UPDATE:UPDATE t1, t2 SET …
1.2 OceanBase更新删除机制
1. 更新机制
– 写入新数据版本
– 保留旧数据版本
– 后台合并清理
2. 删除机制
– 标记删除(软删除)
– 写入删除标记
– 合并时物理删除
3. LSM-Tree特点
– 写放大:更新删除产生多版本
– 读放大:需要合并多版本
– 空间放大:保留历史版本
4. 性能特点
– 写入快:追加写
– 更新慢:需要多版本
– 合并慢:需要整理数据
1.3 OceanBase性能影响因素
1. 索引影响
– 索引越多,更新越慢
– 需要维护所有索引
– 考虑删除不必要的索引
2. 锁影响
– 行锁竞争
– 间隙锁
– 锁等待超时
3. 事务影响
– 事务大小
– 事务隔离级别
– 事务提交频率
4. 并发影响
– 并发更新冲突
– 热点行竞争
– 死锁风险
5. 存储影响
– 写放大
– 合并压力
– 磁盘IO
Part02-生产环境规划与建议
2.1 OceanBase批量大小规划
1. 推荐批量大小
┌─────────────────┬─────────────────────────────────────┐
│ 操作类型 │ 推荐批量大小 │
├─────────────────┼─────────────────────────────────────┤
│ 简单UPDATE │ 1000-5000条 │
│ 复杂UPDATE │ 500-2000条 │
│ 单表DELETE │ 1000-10000条 │
│ 多表DELETE │ 500-2000条 │
│ 有索引表 │ 500-1000条 │
│ 无索引表 │ 2000-5000条 │
└─────────────────┴─────────────────────────────────────┘
2. 影响因素
– 表大小
– 索引数量
– 网络延迟
– 系统负载
3. 测试方法
– 从小到大逐步测试
– 监控响应时间
– 监控系统资源
– 找到最优值
2.2 OceanBase事务规划
1. 事务大小
– 推荐:每事务1000-5000条
– 最大:不超过10000条
– 根据表复杂度调整
2. 事务提交策略
– 定时提交:每N秒
– 定量提交:每N条
– 混合策略
3. 错误处理
– 批量失败重试
– 单条失败记录
– 部分提交处理,风哥提示:。
4. 隔离级别
– READ COMMITTED:推荐
– REPEATABLE READ:避免幻读
– SERIALIZABLE:性能差
2.3 OceanBase索引规划
1. 索引优化原则
– 减少不必要的索引
– 使用覆盖索引
– 避免频繁更新的索引
2. 批量更新前
– 评估索引影响
– 考虑临时禁用索引
– 更新后重建索引
3. 索引维护
$ obclient -h192.168.1.101 -P2881 -uroot@fgedu_tenant -p -e ”
— 查看索引大小
SELECT
index_name,
ROUND(index_length/1024/1024/1024, 2) as index_size_gb
FROM information_schema.statistics
WHERE table_schema = ‘fgedudb’ AND table_name = ‘fgedu_order’;学习交流加群风哥微信: itpux-com。
— 分析索引
ANALYZE TABLE fgedudb.fgedu_order;
”
4. 索引重建
$ obclient -h192.168.1.101 -P2881 -uroot@fgedu_tenant -p -e ”
— 重建索引
ALTER TABLE fgedudb.fgedu_order DROP INDEX idx_status;
ALTER TABLE fgedudb.fgedu_order ADD INDEX idx_status (order_status);
”
Part03-生产环境项目实施方案
3.1 OceanBase批量更新
3.1.1 批量UPDATE
1. 基本语法
$ obclient -h192.168.1.101 -P2881 -uroot@fgedu_tenant -p -e ”
— 单条更新(不推荐)
— UPDATE fgedudb.fgedu_order SET order_status = 1 WHERE order_id = 1;
— UPDATE fgedudb.fgedu_order SET order_status = 1 WHERE order_id = 2;
— 批量更新(推荐)
UPDATE fgedudb.fgedu_order
SET order_status = 1, update_time = NOW()
WHERE order_id IN (1, 2, 3, 4, 5, … , 1000);
”
Query OK, 1000 rows affected
Rows matched: 1000 Changed: 1000 Warnings: 0
Time: 0.8s,学习交流加群风哥QQ113257174。
2. CASE WHEN批量更新
$ obclient -h192.168.1.101 -P2881 -uroot@fgedu_tenant -p -e ”
UPDATE fgedudb.fgedu_order
SET order_status = CASE order_id
WHEN 1 THEN 1
WHEN 2 THEN 2
WHEN 3 THEN 1
ELSE order_status
END,
update_time = NOW()
WHERE order_id IN (1, 2, 3);
”
3. JOIN批量更新
$ obclient -h192.168.1.101 -P2881 -uroot@fgedu_tenant -p -e ”
UPDATE fgedudb.fgedu_order o
JOIN fgedudb.fgedu_order_ext e ON o.order_id = e.order_id
SET o.order_status = e.new_status,
o.update_time = NOW()
WHERE e.process_flag = 0;
”
Query OK, 5000 rows affected
Time: 2.5s
4. 性能对比
– 单条更新1000条:50秒
– 批量更新1000条:0.8秒
– 性能提升:60倍
3.1.2 INSERT ON DUPLICATE KEY UPDATE
$ obclient -h192.168.1.101 -P2881 -uroot@fgedu_tenant -p -e ”
— 插入或更新
INSERT INTO fgedudb.fgedu_order (order_id, user_id, amount, order_status, create_time)
VALUES,更多视频教程www.fgedu.net.cn。
(1, 10001, 199.99, 2, NOW()),
(2, 10002, 299.99, 2, NOW()),
(3, 10003, 399.99, 2, NOW())
ON DUPLICATE KEY UPDATE
order_status = VALUES(order_status),
update_time = NOW();
”
Query OK, 3 rows affected
Records: 3 Duplicates: 2 Warnings: 0
# 说明:
# – 主键不存在则插入
# – 主键存在则更新
# – 适合批量导入场景
3.2 OceanBase批量删除
1. 基本语法
$ obclient -h192.168.1.101 -P2881 -uroot@fgedu_tenant -p -e ”
— 单条删除(不推荐)
— DELETE FROM fgedudb.fgedu_order WHERE order_id = 1;
— DELETE FROM fgedudb.fgedu_order WHERE order_id = 2;
— 批量删除(推荐)
DELETE FROM fgedudb.fgedu_order
WHERE order_id IN (1, 2, 3, 4, 5, … , 1000);
”
Query OK, 1000 rows affected
Time: 0.5s
2. 按条件批量删除
$ obclient -h192.168.1.101 -P2881 -uroot@fgedu_tenant -p -e ”
— 删除30天前的订单
DELETE FROM fgedudb.fgedu_order,更多学习教程公众号风哥教程itpux_com。
WHERE create_time < DATE_SUB(NOW(), INTERVAL 30 DAY)
LIMIT 10000;
"
Query OK, 10000 rows affected
Time: 3.2s
3. 分批删除脚本
#!/bin/bash
# batch_delete.sh
# from:www.itpux.com.qq113257174.wx:itpux-com
# web: http://www.fgedu.net.cn
BATCH_SIZE=10000
TOTAL_DELETED=0
while true; do
RESULT=$(obclient -e "
DELETE FROM fgedudb.fgedu_order
WHERE create_time < DATE_SUB(NOW(), INTERVAL 90 DAY)
LIMIT $BATCH_SIZE;
SELECT ROW_COUNT();
" | tail -1)
if [ "$RESULT" -eq 0 ]; then
break
fi
TOTAL_DELETED=$((TOTAL_DELETED + RESULT))
echo "Deleted $RESULT rows, total: $TOTAL_DELETED",from DB视频:www.itpux.com。
# 暂停1秒,避免压力过大
sleep 1
done
echo "Total deleted: $TOTAL_DELETED rows"
4. 性能对比
- 单条删除1000条:30秒
- 批量删除1000条:0.5秒
- 性能提升:60倍
3.3 OceanBase REPLACE INTO
1. 基本语法
$ obclient -h192.168.1.101 -P2881 -uroot@fgedu_tenant -p -e ”
— REPLACE INTO(先删除后插入)
REPLACE INTO fgedudb.fgedu_order (order_id, user_id, amount, order_status)
VALUES
(1, 10001, 199.99, 2),
(2, 10002, 299.99, 2),
(3, 10003, 399.99, 2);
”
Query OK, 6 rows affected
# 说明:
# – 主键存在则删除旧记录,插入新记录
# – 主键不存在则直接插入
# – 会产生写放大,谨慎使用
2. 与INSERT ON DUPLICATE KEY UPDATE对比
┌──────────────────────────┬──────────────────────────┐
│ REPLACE INTO │ INSERT … ON DUPLICATE │
├──────────────────────────┼──────────────────────────┤
│ 先删除后插入 │ 直接更新 │
│ 产生写放大 │ 写放大较小 │
│ 适合全字段更新 │ 适合部分字段更新 │
│ 性能较差 │ 性能较好 │
└──────────────────────────┴──────────────────────────┘
3. 使用场景
– 数据同步(全量覆盖)
– 数据修复(全字段替换)
– 临时表数据导入
Part04-生产案例与实战讲解
4.1 OceanBase状态批量更新案例
– 订单状态批量更新
– 每日更新:100万条
– 状态:待支付 -> 已支付
# 优化方案
1. 分批更新
#!/bin/bash
# status_update.sh
# from:www.itpux.com.qq113257174.wx:itpux-com
BATCH_SIZE=5000
TOTAL_UPDATED=0
while true; do
RESULT=$(obclient -e ”
UPDATE fgedudb.fgedu_order
SET order_status = 2,
pay_time = NOW(),
update_time = NOW()
WHERE order_status = 1
AND create_time < DATE_SUB(NOW(), INTERVAL 1 HOUR)
LIMIT $BATCH_SIZE;
SELECT ROW_COUNT();
" | tail -1)
if [ "$RESULT" -eq 0 ]; then
break
fi
TOTAL_UPDATED=$((TOTAL_UPDATED + RESULT))
echo "Updated $RESULT rows, total: $TOTAL_UPDATED"
sleep 0.5
done
echo "Total updated: $TOTAL_UPDATED rows"
2. 性能数据
- 数据量:100万条
- 更新时间:10分钟
- 平均速度:1666条/秒
- 系统负载:< 30%
# 更新完成
4.2 OceanBase数据清理批量删除案例
– 历史数据清理
– 清理90天前的日志
– 数据量:5000万条
# 清理方案
1. 创建归档表
$ obclient -h192.168.1.101 -P2881 -uroot@fgedu_tenant -p -e ”
CREATE TABLE fgedudb_archive.fgedu_log_archive LIKE fgedudb.fgedu_log;
”
2. 归档历史数据
#!/bin/bash
# archive_data.sh
# from:www.itpux.com.qq113257174.wx:itpux-com
BATCH_SIZE=10000
TOTAL_ARCHIVED=0
while true; do
# 插入归档表
obclient -e ”
INSERT INTO fgedudb_archive.fgedu_log_archive
SELECT * FROM fgedudb.fgedu_log
WHERE create_time < DATE_SUB(NOW(), INTERVAL 90 DAY)
LIMIT $BATCH_SIZE;
"
# 删除原表数据
RESULT=$(obclient -e "
DELETE FROM fgedudb.fgedu_log
WHERE create_time < DATE_SUB(NOW(), INTERVAL 90 DAY)
LIMIT $BATCH_SIZE;
SELECT ROW_COUNT();
" | tail -1)
if [ "$RESULT" -eq 0 ]; then
break
fi
TOTAL_ARCHIVED=$((TOTAL_ARCHIVED + RESULT))
echo "Archived and deleted $RESULT rows, total: $TOTAL_ARCHIVED"
sleep 1
done
echo "Total archived: $TOTAL_ARCHIVED rows"
3. 性能数据
- 数据量:5000万条
- 处理时间:2小时
- 平均速度:6944条/秒
- 归档表大小:100GB
# 清理完成
4.3 OceanBase数据合并案例
– 增量数据合并
– 每日增量:100万条
– 需要合并到主表
# 合并方案
1. 使用INSERT ON DUPLICATE KEY UPDATE
$ obclient -h192.168.1.101 -P2881 -uroot@fgedu_tenant -p -e ”
— 合并增量数据
INSERT INTO fgedudb.fgedu_order
SELECT * FROM fgedudb.fgedu_order_delta
ON DUPLICATE KEY UPDATE
order_status = VALUES(order_status),
amount = VALUES(amount),
update_time = VALUES(update_time);
”
Query OK, 1000000 rows affected
Records: 800000 Duplicates: 200000 Warnings: 0
Time: 120s
2. 分批合并
#!/bin/bash
# merge_data.sh
# from:www.itpux.com.qq113257174.wx:itpux-com
BATCH_SIZE=50000
OFFSET=0
while true; do
obclient -e ”
INSERT INTO fgedudb.fgedu_order
SELECT * FROM fgedudb.fgedu_order_delta
LIMIT $BATCH_SIZE OFFSET $OFFSET
ON DUPLICATE KEY UPDATE
order_status = VALUES(order_status),
amount = VALUES(amount),
update_time = VALUES(update_time);
”
AFFECTED=$(obclient -e “SELECT ROW_COUNT();” | tail -1)
if [ “$AFFECTED” -eq 0 ]; then
break
fi
OFFSET=$((OFFSET + BATCH_SIZE))
echo “Merged batch at offset $OFFSET”
sleep 0.5
done
3. 性能数据
– 数据量:100万条
– 合并时间:120秒
– 平均速度:8333条/秒
– 新增:80万条
– 更新:20万条
# 合并完成
Part05-风哥经验总结与分享
5.1 OceanBase批量更新删除最佳实践
1. 批量大小
– 根据表复杂度选择
– 一般1000-5000条
– 测试确定最优值
2. 事务管理
– 合理控制事务大小
– 及时提交释放锁
– 错误处理和重试
3. 索引优化
– 减少不必要索引
– 大更新前考虑禁用索引
– 更新后重建索引
4. 并发控制
– 控制并发度
– 避免热点冲突
– 监控锁等待
5. 数据备份
– 操作前备份
– 保留回滚方案
– 验证数据一致性
6. 执行时机
– 选择业务低峰期
– 监控系统负载
– 准备应急预案
5.2 OceanBase性能调优
1. 参数优化
$ obclient -h192.168.1.101 -P2881 -uroot@sys -p -e ”
— 优化事务参数
ALTER SYSTEM SET trx_lock_timeout=10;
ALTER SYSTEM SET trx_try_lock_timeout=0;
— 优化内存参数
ALTER SYSTEM SET memstore_limit_percentage=60;
”
2. SQL优化
– 使用索引
– 避免全表扫描
– 减少锁范围
3. 应用优化
– 批量操作
– 异步处理
– 限流控制
4. 监控脚本
#!/bin/bash
# update_delete_monitor.sh
# from:www.itpux.com.qq113257174.wx:itpux-com
echo “=== Update/Delete Monitor ===”
# 监控锁等待
obclient -e ”
SELECT
COUNT(*) as lock_wait_count,
AVG(wait_time) as avg_wait_time
FROM oceanbase.__all_virtual_lock_wait_stat;
”
# 监控事务
obclient -e ”
SELECT
COUNT(*) as active_trans,
AVG(elapsed_time) as avg_trans_time
FROM oceanbase.__all_virtual_trans_stat;
”
echo “=============================”
5.3 OceanBase常见问题
Q1: 批量更新报锁超时?
A1: 减小批量大小,调整锁超时参数,避免热点
Q2: 批量删除速度慢?
A3: 分批删除,删除前禁用索引,业务低峰期执行
Q3: 更新后查询变慢?
A3: 等待合并完成,或手动触发合并
Q4: 批量操作影响业务?
A4: 控制并发度,限流,选择低峰期执行
Q5: 如何监控批量操作进度?
A5: 分批输出进度,使用ROW_COUNT()统计
Q6: 批量更新产生大量版本?
A6: 这是LSM-Tree特性,合并后会清理
Q7: 如何避免死锁?
A7: 统一访问顺序,减小事务,及时提交
Q8: 批量操作失败如何回滚?
A8: 使用事务,失败回滚,记录失败数据
Q9: REPLACE INTO和UPDATE哪个好?
A9: UPDATE性能更好,REPLACE INTO适合全字段替换
Q10: 大批量删除如何优化?
A10: 分批删除,归档后删除,使用TRUNCATE(全表)
本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.html
