风哥教程参考DB2官方文档Performance Monitoring and Tuning Guide、SQL Reference等内容,详细介绍DB2慢查询的识别、分析方法、优化技术以及在生产环境中的最佳实践。更多视频教程www.fgedu.net.cn
目录大纲
Part01-慢查询基础概念
慢查询是指执行时间超过预设阈值的SQL语句,通常表现为:
- 执行时间过长
- CPU使用率高
- IO操作频繁
- 内存使用过高
- 锁定时间长
- 系统性能下降
- 用户体验变差
- 资源浪费
- 可能导致系统崩溃
- 影响其他查询的执行
- SQL语句编写不当
- 缺少索引或索引失效
- 表结构设计不合理
- 统计信息过时
- 数据库参数配置不当
- 系统资源不足
Part02-生产环境慢查询识别与监控
- 使用DB2快照监控
- 启用DB2语句事件监视器
- 使用第三方监控工具
- 分析应用程序日志
- 定期执行性能报表
$ su – db2inst1
$ db2 “CREATE EVENT MONITOR stmt_monitor FOR STATEMENTS WRITE TO TABLE”
# 启动事件监视器
$ db2 “SET EVENT MONITOR stmt_monitor STATE 1”
# 查看事件监视器状态
$ db2 “SELECT * FROM SYSCAT.EVENTMONITORS WHERE NAME = ‘STMT_MONITOR'”
# 查看捕获的语句
$ db2 “SELECT * FROM STMT_MONITOR.STATEMENTS”
# 查找慢查询
$ db2 “SELECT STMT_TEXT, EXECUTION_TIME, CPU_TIME FROM STMT_MONITOR.STATEMENTS WHERE EXECUTION_TIME > 1000 ORDER BY EXECUTION_TIME DESC”
# 关闭事件监视器
$ db2 “SET EVENT MONITOR stmt_monitor STATE 0”
# 删除事件监视器
$ db2 “DROP EVENT MONITOR stmt_monitor”
$ su – db2inst1
$ db2 “GET SNAPSHOT FOR DATABASE ON fgedb”
# 获取语句快照
$ db2 “GET SNAPSHOT FOR DYNAMIC SQL ON fgedb”
# 查找执行时间长的语句
$ db2 “GET SNAPSHOT FOR DYNAMIC SQL ON fgedb” | grep -A 5 “Elapsed Time”
# 使用db2top监控
$ db2top
# 在db2top中查看慢查询
# 按’s’键查看SQL语句
# 按’L’键查看锁信息
# 按’m’键查看内存使用
# 使用db2pd监控
$ db2pd -d fgedb -stmt
$ db2pd -d fgedb -trans
$ db2pd -d fgedb -locks
Part03-生产环境慢查询分析与优化方案
$ su – db2inst1
$ db2 “EXPLAIN PLAN FOR SELECT * FROM fgedu_order WHERE order_amount > 1000”
# 查看执行计划
$ db2 “SELECT * FROM EXPLAIN_INSTANCE”
$ db2 “SELECT * FROM EXPLAIN_STATEMENT”
$ db2 “SELECT * FROM EXPLAIN_OPERATOR”
# 使用db2exfmt查看执行计划
$ db2exfmt -d fgedb -1 -o explain_output.txt
# 分析执行计划输出
$ cat explain_output.txt
# 检查索引使用情况
$ db2 “SELECT * FROM EXPLAIN_INDEXES”
# 检查表访问情况
$ db2 “SELECT * FROM EXPLAIN_TABLES”
# 分析统计信息
$ db2 “RUNSTATS ON TABLE fgedu_order”
$ db2 “SELECT * FROM SYSSTAT.TABLES WHERE TABNAME = ‘FGEDU_ORDER'”
$ db2 “SELECT * FROM SYSSTAT.INDEXES WHERE TABNAME = ‘FGEDU_ORDER'”
$ db2 “SELECT * FROM fgedu_order WHERE order_amount > 1000”
# 优化后的查询
$ db2 “SELECT order_id, user_id, order_amount FROM fgedu_order WHERE order_amount > 1000”
# 添加索引
$ db2 “CREATE INDEX idx_order_amount ON fgedu_order(order_amount)”
# 优化JOIN查询
$ db2 “SELECT o.order_id, o.user_id, o.order_amount, u.username FROM fgedu_order o JOIN fgedu_user u ON o.user_id = u.user_id WHERE o.order_amount > 1000”
# 优化后
$ db2 “CREATE INDEX idx_user_id ON fgedu_order(user_id)”
$ db2 “SELECT o.order_id, o.user_id, o.order_amount, u.username FROM fgedu_order o JOIN fgedu_user u ON o.user_id = u.user_id WHERE o.order_amount > 1000”
# 优化子查询
$ db2 “SELECT * FROM fgedu_order WHERE user_id IN (SELECT user_id FROM fgedu_user WHERE status = ‘active’)”
# 优化后
$ db2 “SELECT o.* FROM fgedu_order o JOIN (SELECT DISTINCT user_id FROM fgedu_user WHERE status = ‘active’) u ON o.user_id = u.user_id”
# 优化聚合查询
$ db2 “SELECT user_id, SUM(order_amount) FROM fgedu_order GROUP BY user_id”
# 优化后
$ db2 “CREATE INDEX idx_user_id_amount ON fgedu_order(user_id, order_amount)”
$ db2 “SELECT user_id, SUM(order_amount) FROM fgedu_order GROUP BY user_id”
# 优化排序
$ db2 “SELECT * FROM fgedu_order ORDER BY create_time DESC”
# 优化后
$ db2 “CREATE INDEX idx_create_time ON fgedu_order(create_time)”
$ db2 “SELECT order_id, user_id, order_amount FROM fgedu_order ORDER BY create_time DESC”
$ db2 “SELECT * FROM SYSSTAT.INDEXES WHERE TABNAME = ‘FGEDU_ORDER'”
# 检查索引效率
$ db2 “RUNSTATS ON TABLE fgedu_order WITH DISTRIBUTION AND DETAILED INDEXES ALL”
# 添加合适的索引
$ db2 “CREATE INDEX idx_order_amount ON fgedu_order(order_amount)”
$ db2 “CREATE INDEX idx_user_id_create_time ON fgedu_order(user_id, create_time)”
# 重建索引
$ db2 “REORG INDEXES ALL FOR TABLE fgedu_order”
# 删除无用索引
$ db2 “DROP INDEX idx_unused_index”
# 分析索引使用情况
$ db2 “SELECT * FROM SYSIBMADM.INDEXUSAGE WHERE TABNAME = ‘FGEDU_ORDER'”
# 索引设计最佳实践
# 1. 为经常查询的列创建索引
# 2. 为JOIN条件列创建索引
# 3. 为ORDER BY和GROUP BY列创建索引
# 4. 避免过多索引
# 5. 定期维护索引
$ db2 “CREATE BUFFERPOOL bp_8k SIZE 1000 PAGESIZE 8K”
$ db2 “ALTER TABLESPACE USERSpace BUFFERPOOL bp_8k”
# 优化查询优化器
$ db2 “UPDATE DATABASE CONFIGURATION FOR fgedb USING QUERYOPT 5”
# 优化排序堆
$ db2 “UPDATE DATABASE CONFIGURATION FOR fgedb USING SORTHEAP 1024”
# 优化包缓存
$ db2 “UPDATE DATABASE CONFIGURATION FOR fgedb USING PCKCACHESZ 1024”
# 优化锁列表
$ db2 “UPDATE DATABASE CONFIGURATION FOR fgedb USING LOCKLIST 1024”
# 优化日志缓冲区
$ db2 “UPDATE DATABASE CONFIGURATION FOR fgedb USING LOGBUFSZ 1024”
# 优化最大应用程序数
$ db2 “UPDATE DATABASE CONFIGURATION FOR fgedb USING MAXAPPLS 1000”
# 查看当前配置
$ db2 “GET DATABASE CONFIGURATION FOR fgedb”
# 监控参数效果
$ db2 “GET SNAPSHOT FOR DATABASE ON fgedb”
Part04-慢查询优化实战案例
$ db2 “SELECT * FROM fgedu_order WHERE order_amount > 5000”
# 分析执行计划
$ db2 “EXPLAIN PLAN FOR SELECT * FROM fgedu_order WHERE order_amount > 5000”
$ db2exfmt -d fgedb -1 -o explain_output.txt
# 发现使用全表扫描
# 解决方案:添加索引
$ db2 “CREATE INDEX idx_order_amount ON fgedu_order(order_amount)”
# 重新执行查询
$ db2 “SELECT * FROM fgedu_order WHERE order_amount > 5000”
# 验证执行计划
$ db2 “EXPLAIN PLAN FOR SELECT * FROM fgedu_order WHERE order_amount > 5000”
$ db2exfmt -d fgedb -1 -o explain_output_optimized.txt
# 确认使用索引扫描
# 性能提升:执行时间从5秒减少到0.1秒
$ db2 “SELECT o.order_id, o.user_id, o.order_amount, u.username, u.email FROM fgedu_order o JOIN fgedu_user u ON o.user_id = u.user_id WHERE o.order_amount > 1000”
# 分析执行计划
$ db2 “EXPLAIN PLAN FOR SELECT o.order_id, o.user_id, o.order_amount, u.username, u.email FROM fgedu_order o JOIN fgedu_user u ON o.user_id = u.user_id WHERE o.order_amount > 1000”
# 发现JOIN操作效率低
# 解决方案:添加索引
$ db2 “CREATE INDEX idx_order_user_id ON fgedu_order(user_id)”
$ db2 “CREATE INDEX idx_user_user_id ON fgedu_user(user_id)”
# 重新执行查询
$ db2 “SELECT o.order_id, o.user_id, o.order_amount, u.username, u.email FROM fgedu_order o JOIN fgedu_user u ON o.user_id = u.user_id WHERE o.order_amount > 1000”
# 性能提升:执行时间从10秒减少到0.5秒
$ db2 “SELECT user_id, COUNT(*), SUM(order_amount) FROM fgedu_order GROUP BY user_id HAVING SUM(order_amount) > 10000”
# 分析执行计划
$ db2 “EXPLAIN PLAN FOR SELECT user_id, COUNT(*), SUM(order_amount) FROM fgedu_order GROUP BY user_id HAVING SUM(order_amount) > 10000”
# 发现聚合操作效率低
# 解决方案:添加复合索引
$ db2 “CREATE INDEX idx_user_id_amount ON fgedu_order(user_id, order_amount)”
# 重新执行查询
$ db2 “SELECT user_id, COUNT(*), SUM(order_amount) FROM fgedu_order GROUP BY user_id HAVING SUM(order_amount) > 10000”
# 性能提升:执行时间从8秒减少到0.3秒
$ db2 “SELECT * FROM fgedu_order ORDER BY create_time DESC LIMIT 10”
# 分析执行计划
$ db2 “EXPLAIN PLAN FOR SELECT * FROM fgedu_order ORDER BY create_time DESC LIMIT 10”
# 发现排序操作效率低
# 解决方案:添加索引
$ db2 “CREATE INDEX idx_create_time ON fgedu_order(create_time)”
# 重新执行查询
$ db2 “SELECT order_id, user_id, order_amount, create_time FROM fgedu_order ORDER BY create_time DESC LIMIT 10”
# 性能提升:执行时间从6秒减少到0.2秒
Part05-风哥经验总结与分享
- 定期分析慢查询:建立慢查询监控机制
- 优化SQL语句:避免全表扫描和复杂子查询
- 合理设计索引:为频繁查询的列创建索引
- 维护统计信息:定期运行RUNSTATS
- 优化数据库参数:根据系统情况调整配置
- 索引失效:检查索引是否被正确使用
- 统计信息过时:运行RUNSTATS更新统计信息
- 锁竞争:优化事务和SQL语句
- 内存不足:调整内存参数配置
- IO瓶颈:优化存储和SQL语句
- 使用参数化查询:避免SQL注入和提高缓存效率
- 限制结果集大小:使用LIMIT或FETCH FIRST
- 避免SELECT *:只查询需要的列
- 使用EXPLAIN分析执行计划:了解查询执行情况
- 定期维护数据库:RUNSTATS、REORG等操作
- 监控慢查询:建立慢查询告警机制
- 优化JOIN操作:合理使用JOIN顺序和类型
- 考虑分区表:对于大表使用分区技术
学习交流加群风哥微信: itpux-com
更多视频教程www.fgedu.net.cn
from:www.itpux.com.qq113257174.wx:itpux-com
本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.html
