SQL调优 - Hints指定索引 解决慢查询案例
2016-03-22 21:18
316 查看
背景
每当交易高峰时期,可能会暴露一些平时无法发现的问题,机遇和挑战并存。下面聊聊最近解决的一个案例,因为执行计划走错导致慢查询,进而引发应用线程阻塞、线程池爆满,最后应用功能瘫痪。如何标本兼治的解决问题,需要很多思考。
问题分析
step1 应用瘫痪
用户反应某查询功能一直处于加载中,并出现错误提示。查看后台应用日志,调用远程查询服务出现大量超时。
step2 线程池爆满
通过jstack命令来分析查询服务jvm线程堆栈,发现设定的线程池已经满了,而且大部分线程阻塞在了数据库查询阶段(如下图),看来是有很多慢查询。![](https://note.wiz.cn/api/document/files/unzip/61d56e16-16ae-11e2-beee-aec9e521f360/98b57485-5373-411a-91f5-91e79995c002.3374/index_files/14420406.png)
step3 慢查询的由来 - 错误执行计划
为何忽然出现这么多慢查询?我们来分析一下:SELECT no, time
FROM tablename
where no = :1
and time >= to_date(:2, 'yyyy-mm-dd')
and time < to_date(:3, 'yyyy-mm-dd')
ORDER BY time DESC
[/code]
注:条件字段(no、time)分别有索引(idx_no、idx_time)。
经过DBA帮助,分析上段sql的执行计划发现:
有时数据库会走idx_no索引,查询很快
![](https://note.wiz.cn/api/document/files/unzip/61d56e16-16ae-11e2-beee-aec9e521f360/98b57485-5373-411a-91f5-91e79995c002.3374/index_files/15764966.png)
有时会走idx_time索引,查询很慢
![](https://note.wiz.cn/api/document/files/unzip/61d56e16-16ae-11e2-beee-aec9e521f360/98b57485-5373-411a-91f5-91e79995c002.3374/index_files/4874030.png)
解决方案
既然数据库自动生成的执行计划有时会出问题,那么我们可以用hints语句指定当前sql走哪条索引,以固定执行计划。下面以Oracle为例,添加hints:
![](https://note.wiz.cn/api/document/files/unzip/61d56e16-16ae-11e2-beee-aec9e521f360/98b57485-5373-411a-91f5-91e79995c002.3374/index_files/6420274.png)
SELECT /*+ index(tablename IDX_NO) */ no, time
FROM tablename
where no = :1
and time >= to_date(:2, 'yyyy-mm-dd')
and time < to_date(:3, 'yyyy-mm-dd')
ORDER BY time DESC
[/code]
如果感觉在sql中添加不方便的话,oracle 10g以上版本提供了SQL
Profile方式。
总结思考
这个问题应该一直有,为何在交易高峰时段才表现出来值得去研究。数据库:平时数据库压力较小,出现几个走错执行计划的慢查询,也只是让数据库压力比均值高出一小部分,性能未受影响。但是,高峰时段数据库本身就处于一个高负载状态,这时出现的慢查询无疑是雪上加霜,接近某个临界点时性能就明显下滑。
应用:慢查询会导致线程阻塞等待,一直占用线程池资源。我们知道,用户在点击查询按钮后发现一直加载,会不知觉多点几遍。这样的话,线程数量暴涨且大部分处于阻塞状态,线程池满了之后应用就会瘫痪掉,使其他正常的接口也无法正常工作。
综上所述,数据层的优化是治本,同时还要借助一些手段来保证不出现雪崩式性能下降。比如,在前台页面添加重复提交限制,尽量避免短时间内产生大量慢查询。
参考资料
Oracle Hints:https://docs.oracle.com/cd/B12037_01/server.101/b10752/hintsref.htm#5156Oracle SQL Profile:https://docs.oracle.com/database/121/TGSQL/tgsql_profiles.htm#TGSQL596
相关文章推荐
- oracle 转 mysql 最新有效法(转)
- mysql 安装后报 ERROR 1045 (28000): Access denied for user 'root'@'localhost'
- 爱分享 » 30多条mysql数据库优化方法,千万级数据库记录查询轻松解决
- 3.22数据库基础知识:①数据类型②基本规则③数据库基本操作,增删改库,表
- Oracle数据仓库创建教程
- Oracle数据仓库创建教程
- 如何实现在Oracle中应用存储过程调用MatLab函数(3)
- 关于oracle数据库(7)查询1
- mysql设置远程IP地址访问数据库
- MySQL数据引擎及索引介绍
- Hive官方手册学习(三)Hive数据操作语言
- mysql
- 送Vcenter数据库导出虚拟机主要信息报表
- MySQL之创建与操作数据表
- mysql多实例的配置(转)
- Oracle Day05 集合与数据处理
- Mysql 命令行快速导入数据
- mysql 删除前几天记录
- MySQL 存储过程和函数(转)
- MySQL 批量Dll操作(转)