SQL调优 - Hints指定索引 解决慢查询案例
背景
每当交易高峰时期,可能会暴露一些平时无法发现的问题,机遇和挑战并存。下面聊聊最近解决的一个案例,因为执行计划走错导致慢查询,进而引发应用线程阻塞、线程池爆满,最后应用功能瘫痪。如何标本兼治的解决问题,需要很多思考。
问题分析
step1 应用瘫痪
用户反应某查询功能一直处于加载中,并出现错误提示。查看后台应用日志,调用远程查询服务出现大量超时。
step2 线程池爆满
通过jstack命令来分析查询服务jvm线程堆栈,发现设定的线程池已经满了,而且大部分线程阻塞在了数据库查询阶段(如下图),看来是有很多慢查询。

step3 慢查询的由来 - 错误执行计划
为何忽然出现这么多慢查询?我们来分析一下:
SELECT no, timeFROM tablenamewhere no = :1and time >= to_date(:2, 'yyyy-mm-dd')and time < to_date(:3, 'yyyy-mm-dd')ORDER BY time DESC
注:条件字段(no、time)分别有索引(idx_no、idx_time)。
经过DBA帮助,分析上段sql的执行计划发现:
有时数据库会走idx_no索引,查询很快

有时会走idx_time索引,查询很慢

解决方案
既然数据库自动生成的执行计划有时会出问题,那么我们可以用hints语句指定当前sql走哪条索引,以固定执行计划。
下面以Oracle为例,添加hints:

SELECT /*+ index(tablename IDX_NO) */ no, timeFROM tablenamewhere no = :1and time >= to_date(:2, 'yyyy-mm-dd')and time < to_date(:3, 'yyyy-mm-dd')ORDER BY time DESC
如果感觉在sql中添加不方便的话,oracle 10g以上版本提供了SQL Profile方式。
总结思考
这个问题应该一直有,为何在交易高峰时段才表现出来值得去研究。
数据库:平时数据库压力较小,出现几个走错执行计划的慢查询,也只是让数据库压力比均值高出一小部分,性能未受影响。但是,高峰时段数据库本身就处于一个高负载状态,这时出现的慢查询无疑是雪上加霜,接近某个临界点时性能就明显下滑。
应用:慢查询会导致线程阻塞等待,一直占用线程池资源。我们知道,用户在点击查询按钮后发现一直加载,会不知觉多点几遍。这样的话,线程数量暴涨且大部分处于阻塞状态,线程池满了之后应用就会瘫痪掉,使其他正常的接口也无法正常工作。
综上所述,数据层的优化是治本,同时还要借助一些手段来保证不出现雪崩式性能下降。比如,在前台页面添加重复提交限制,尽量避免短时间内产生大量慢查询。
参考资料
Oracle Hints:https://docs.oracle.com/cd/B12037_01/server.101/b10752/hintsref.htm#5156
Oracle SQL Profile:https://docs.oracle.com/database/121/TGSQL/tgsql_profiles.htm#TGSQL596
SQL调优 - Hints指定索引 解决慢查询案例的更多相关文章
- MySQL索引和SQL调优手册
MySQL索引 MySQL支持诸多存储引擎,而各种存储引擎对索引的支持也各不相同,因此MySQL数据库支持多种索引类型,如BTree索引,哈希索引,全文索引等等.为了避免混乱,本文将只关注于BTree ...
- Oracle性能调优之虚拟索引用法简介
本博客记录一下Oracle虚拟索引的用法,虚拟索引是定义在数据字典中的伪索引,可以说是伪列,没有修改的索引字段的.虚拟索引的目的模拟索引,不会增加存储空间的使用,有了虚拟索引,开发者使用执行计划的时候 ...
- 《高性能SQL调优精要与案例解析》一书谈主流关系库SQL调优(SQL TUNING或SQL优化)核心机制之——索引(index)
继<高性能SQL调优精要与案例解析>一书谈SQL调优(SQL TUNING或SQL优化),我们今天就谈谈各主流关系库中,占据SQL调优技术和工作半壁江山的.最重要的核心机制之一——索引(i ...
- 你们一般都是怎么进行SQL调优的?MySQL在执行时是如何选择索引的?
前言 过年回来的第二周了,终于有时间继续总结知识了.这次来看一下SQL调优的知识,这类问题基本上面试的时候都会被问到,无论你的岗位是后端,运维,测试等等. 像本文标题中的两个问题,就是我在实际面试过程 ...
- OCM_第十四天课程:Section6 —》数据库性能调优_各类索引 /调优工具使用/SQL 优化建议
注:本文为原著(其内容来自 腾科教育培训课堂).阅读本文注意事项如下: 1:所有文章的转载请标注本文出处. 2:本文非本人不得用于商业用途.违者将承当相应法律责任. 3:该系列文章目录列表: 一:&l ...
- SQL调优
# 问题的提出 在应用系统开发初期,由于开发数据库数据比较少,对于查询SQL语句,复杂视图的的编写等体会不出SQL语句各种写法的性能优劣,但是如果将应用 系统提交实际应用后,随着数据库中数据的增加,系 ...
- Oracle SQL 调优健康检查脚本
Oracle SQL 调优健康检查脚本 我们关注数据库系统的性能,进行数据库调优的主要工作就是进行SQL的优化.良好的数据架构设计.配合应用系统中间件和写一手漂亮的SQL,是未来系统上线后不出现致命性 ...
- Oracle SQL调优记录
目录 一.前言 二.注意点 三.Oracle执行计划 四.调优记录 @ 一.前言 本博客只记录工作中的一次oracle sql调优记录,因为数据量过多导致的查询缓慢,一方面是因为业务太过繁杂,关联了太 ...
- 《高性能SQL调优精要与案例解析》一书谈SQL调优(SQL TUNING或SQL优化)学习
<高性能SQL调优精要与案例解析>一书上市发售以来,很多热心读者就该书内容及一些具体问题提出了疑问,因读者众多外加本人日常工作的繁忙 ,在这里就SQL调优学习进行讨论并对热点问题统一作答. ...
随机推荐
- C#学习之Linq to Xml
前言 我相信很多从事.NET开发的,在.NET 3.5之前操作XML会比较麻烦,但是在此之后出现了Linq to Xml,而今天的主人公就是Linq to Xml,废话不多说,直接进入主题. 题外:最 ...
- 分分钟用上C#中的委托和事件之窗体篇
上次以鸿门宴的例子写了一篇名为<分分钟用上C#中的委托和事件>的博文,旨在帮助C#初学者迈过委托和事件这道坎,能够用最快的速度掌握如何使用它们.如果觉得意犹未尽,或者仍然不知如何在实际应用 ...
- Spec模板
Spec模板 一.概述 1.项目背景 图书馆在正常运营中面对大量书籍.读者信息以及两者间相互联系产生的借书信息.还书信息.现有的人工记录方法既效率低又错误过多,大大影响了图书馆 ...
- 自己动手写客户端UI库——创建第一个控件
在上一篇文章中我们主要讲了C#如何和JS通信, 这一篇文章中,我们将创建一个最基础的Button控件 WUI库中控件的继承机制 我们先解释最简单的继承机制,以后WUI库的继承机制会比这个复杂的多 ...
- C语言宏高级用法 [总结]
1.前言 今天看代码时候,遇到一些宏,之前没有见过,感觉挺新鲜.如是上网google一下,顺便总结一下,方便以后学习和运用.C语言程序中广泛的使用宏定义,采用关键字define进行定义,宏只是一种简 ...
- [RabbitMQ] Connection failed
RabbitMQ.Client.Exceptions.BrokerUnreachableException: None of the specified endpoints were reachabl ...
- 构建单页Web应用
摘自前端农民工的博客 让我们先来看几个网站: coding teambition cloud9 注意这几个网站的相同点,那就是在浏览器中,做了原先“应当”在客户端做的事情.它们的界面切换非常流畅,响应 ...
- vs emulator for android使用
在windows上调试android程序,可以利用hyperv虚拟化功能,微软也提供了模拟工具和android studio.eclipse的配置说明,不再累述. 关于启动vs模拟器的cmd命令: e ...
- atitit.泛型编程总结最佳实践 vO99 java c++ c#.net php
atitit.泛型编程总结最佳实践 vO99 java c++ c#.net php \ 1. 泛型历史 1 由来 1 2. 泛型的机制编辑 1 机制 1 编译机制 2 3. 泛型方法定义1::前定义 ...
- python中的metaclass
首先看下面的代码: # coding: utf-8 class Test(object): pass print Test.__class__ # type print Test.__base__ # ...