SQL使用复合索引实现数据库查询的优化


Posted in SQL Server onMay 25, 2022

一 问题

程序再在一次查询时出现查询时间过长,每次查询要1-2分钟业务反馈用户操作体验很差,sql如下:

select *
FROM edi_booking edibooking0_
WHERE 1 = 1
        AND edibooking0_.load_port_code IN ('CNCWN', 'CNDCB', 'AA', 'CNMWN'
        , 'CWHSD', 'CNSHK', 'CNYTN', 'CNSKU')
        AND edibooking0_.carrier_code = 'WHL'
        AND upper(edibooking0_.so_no) LIKE upper('025%')
        AND edibooking0_.load_port_code = 'CNSHK'
        AND edibooking0_.status <= 1
        AND edibooking0_.tfc_code = 'E19957'
ORDER BY edibooking0_.so_no ASC;

需要对查询进行优化。

二 分析

还是老样子,先看看执行计划,看看走没走索引,不查不知道一查吓一跳,执行计划上居然显示走了索引,索引是函数索引upper(so_no) ,走了索引为什么还慢呢,根据以往的经验,走了索引不是应该很快才对吗?奇奇怪怪,于是注意到了查询条件中还有一个条件tfc_code,又发现这个字段其实也有建立索引,是不是数据库的执行计划有问题,没有走tfc_code索引呢?或者说tfc_code索引本身有问题,于是进行重建tfc_code索引

alter index EDI_BOOKING_IDX_TFC_CODE rebuild online;

执行后,哇塞,查询速度果然上来了,2s钟返回查询结果。查看执行计划,走了tfc_code索引,nice! 但是故事还没有结束! 过了一天后,业务又反馈查询慢了,查看执行计划,走的索引又变成了upper(so_no)。让人头秃。

那还个方向思考,既然走了索引,为什么还会慢!!! 原来走了索引并不一定就会快,这是一个大大的误区。

upper(edibooking0_.so_no) LIKE upper('025%')这个过滤条件走了索引,但是索引的类型是range_scan,这种类型查询返回的数据量会比较大,这就是这次走索引还慢的问题所在,因为走了索引之后返回了150w条数据,而150w条数据被后去的条件过滤,这样导致了查询速度慢的问题。

而引发这个问题,一个是upper(so_no)索引返回数据量大,另外一个就是oracle的执行计划没有选择最优的索引,如果选择tfc_code索引,那么查询也会很快。

三 解决方案

指定数据库选择索引:

由于执行计划是数据库自动生成的,我们无法改变执行计划,但是我们可以通过指定索引的方式,让数据库去执行我们指定的索引,如:

select /*+index(edibooking0_ IDX_EDI_BOOKING_SO_TFC_CT)*/*
FROM edi_booking edibooking0_

但是这种有一个弊端,要对每一个执行的语句都要进行指定索引,修改量比较大。

建立复合索引:

CREATE INDEX IDX_EDI_BOOKING_SO_TFC_CT
ON edi_booking (UPPER("SO_NO"), "TFC_CODE","CONTRACT_NO");

复合索引很容易给人一种鸡肋的感觉,因为他对应的查询条件一定是他最左边的索引字段被查询才能生效,但是其实他是非常有用的,比如我们现在的场景,进行复核索引过滤时就会产生非常大的性能提升,最终通过建立组合索引解决问题

到此这篇关于SQL使用复合索引实现数据库查询的优化的文章就介绍到这了!


Tags in this post...

SQL Server 相关文章推荐
SQL Server连接查询的实用教程
Apr 07 SQL Server
SQLServer 日期函数大全(小结)
Apr 08 SQL Server
SqlServer数据库远程连接案例教程
Jul 15 SQL Server
Windows环境下实现批量执行Sql文件
Oct 05 SQL Server
MySQL 中如何归档数据的实现方法
Mar 16 SQL Server
SQL Server实现分页方法介绍
Mar 16 SQL Server
使用MybatisPlus打印sql语句
Apr 22 SQL Server
SQL Server 忘记密码以及重新添加新账号
Apr 26 SQL Server
SQL解决未能删除约束问题drop constraint
May 30 SQL Server
在SQL Server中使用 Try Catch 处理异常的示例详解
Jul 15 SQL Server
详解SQL报错盲注
Jul 23 SQL Server
SQL Server中的逻辑函数介绍
May 25 #SQL Server
SQL Server删除表中的重复数据
May 25 #SQL Server
SQL Server中T-SQL标识符介绍与无排序生成序号的方法
May 25 #SQL Server
SQL Server一个字符串拆分多行显示或者多行数据合并成一个字符串
May 25 #SQL Server
SQL Server使用CROSS APPLY与OUTER APPLY实现连接查询
May 25 #SQL Server
SQL Server使用PIVOT与unPIVOT实现行列转换
May 25 #SQL Server
SQL SERVER中的流程控制语句
May 25 #SQL Server
You might like
坏狼php学习 计数器实例代码
2008/06/15 PHP
PHP 开源AJAX框架14种
2009/08/24 PHP
PHP入门教程之正则表达式基本用法实例详解(正则匹配,搜索,分割等)
2016/09/11 PHP
php中文字符串截取多种方法汇总
2016/10/06 PHP
laravel返回统一格式错误码问题
2019/11/04 PHP
Laravel 手动开关 Eloquent 修改器的操作方法
2019/12/30 PHP
JavaScript 一道字符串分解的题目
2011/08/03 Javascript
js Form.elements[i]的使用实例
2011/11/13 Javascript
JavaScript之Getters和Setters 平台支持等详细介绍
2012/12/07 Javascript
实测jquery data()如何存值
2013/08/18 Javascript
优化javascript的执行效率一些方法总结
2013/12/25 Javascript
jQuery 获取页面li数组并删除不在数组中的key
2016/08/02 Javascript
jquery滚动条插件slimScroll使用方法
2017/02/09 Javascript
收集前端面试题之url、href、src
2018/03/22 Javascript
JS实现对json对象排序并删除id相同项功能示例
2018/04/18 Javascript
Vue 实现拖动滑块验证功能(只有css+js没有后台验证步骤)
2018/08/24 Javascript
在angularJs中进行数据遍历的2种方法
2018/10/08 Javascript
浅谈webpack+react多页面开发终极架构
2018/11/11 Javascript
vue.js实现三级菜单效果
2019/10/19 Javascript
vue路由切换时取消之前的所有请求操作
2020/09/01 Javascript
python 垃圾收集机制的实例详解
2017/08/20 Python
numpy数组做图片拼接的实现(concatenate、vstack、hstack)
2019/11/08 Python
Python安装whl文件过程图解
2020/02/18 Python
Python reduce函数作用及实例解析
2020/05/08 Python
Python如何在循环内使用list.remove()
2020/06/01 Python
纯css3使用vw和vh实现自适应的方法
2018/02/09 HTML / CSS
美国知名的百货清仓店:Neiman Marcus Last Call
2016/08/03 全球购物
英国独特的时尚和生活方式品牌:JOY
2018/03/17 全球购物
西班牙著名的珠宝首饰品牌:P D PAOLA
2018/09/15 全球购物
请说出你所知道的线程同步的方法
2013/04/19 面试题
运动会稿件200字
2014/02/07 职场文书
《草虫的村落》教学反思
2014/02/16 职场文书
万里长城导游词
2015/01/30 职场文书
会计主管岗位职责
2015/04/02 职场文书
大国崛起观后感
2015/06/02 职场文书
《吸血鬼:避世 血猎》官宣4.27发售 系列首款大逃杀
2022/04/03 其他游戏