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 相关文章推荐
2021-4-3课程——SQL Server查询【2】
Apr 05 SQL Server
SQL 尚未定义空闲 CPU 条件 - OnIdle 作业计划将不起任何作用
Jun 30 SQL Server
数据库之SQL技巧整理案例
Jul 07 SQL Server
SqlServer数据库远程连接案例教程
Jul 15 SQL Server
SQLServer之常用函数总结详解
Aug 30 SQL Server
万能密码的SQL注入漏洞其PHP环境搭建及防御手段
Sep 04 SQL Server
sql时间段切分实现每隔x分钟出一份高速门架车流量
Feb 28 SQL Server
sql server偶发出现死锁的解决方法
Apr 10 SQL Server
SQL Server一个字符串拆分多行显示或者多行数据合并成一个字符串
May 25 SQL Server
SQL Server数据库备份和恢复数据库的全过程
Jun 14 SQL Server
SqlServer常用函数及时间处理小结
May 08 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配置文件中最常用四个ini函数
2007/03/19 PHP
php微信支付接口开发程序
2016/08/02 PHP
Javascript的IE和Firefox兼容性汇编
2006/07/01 Javascript
添加到收藏夹代码(兼容几乎所有的浏览器)
2007/01/09 Javascript
Prototype Object对象 学习
2009/07/12 Javascript
js实现杯子倒水问题自动求解程序
2013/03/25 Javascript
仿谷歌主页js动画效果实现代码
2013/07/14 Javascript
详解JavaScript中的every()方法
2015/06/08 Javascript
JS简单编号生成器实现方法(附demo源码下载)
2016/04/05 Javascript
基于BootStrap Metronic开发框架经验小结【六】对话框及提示框的处理和优化
2016/05/12 Javascript
深入理解JavaScript 函数
2016/06/06 Javascript
js日期相关函数dateAdd,dateDiff,dateFormat等介绍
2016/09/24 Javascript
js实现hashtable的赋值、取值、遍历操作实例详解
2016/12/25 Javascript
bootstrap table实例详解
2017/01/06 Javascript
jQuery表单插件ajaxForm实例详解
2017/01/17 Javascript
BootStrap导航栏问题记录
2017/07/31 Javascript
vue使用ElementUI时导航栏默认展开功能的实现
2018/07/04 Javascript
实例讲解JavaScript截取字符串
2018/11/30 Javascript
Vue学习之组件用法实例详解
2020/01/06 Javascript
Jquery+AJAX实现无刷新上传并重命名文件操作示例【PHP后台接收】
2020/05/29 jQuery
python局域网ip扫描示例分享
2014/04/03 Python
使用Python将图片转正方形的两种方法实例代码详解
2020/04/29 Python
python3.7.3版本和django2.2.3版本是否可以兼容
2020/09/01 Python
英国家喻户晓的折扣商场:TK Maxx
2017/05/26 全球购物
KIKO MILANO英国官网:意大利知名化妆品和护肤品品牌
2017/09/25 全球购物
加拿大奢华时装品牌:Mackage
2018/01/10 全球购物
假日旅行社实习自我鉴定
2013/09/24 职场文书
实习自我评价怎么写
2013/12/02 职场文书
经典优秀毕业生求职信范文分享
2013/12/18 职场文书
英语系本科生求职信
2014/07/15 职场文书
四风对照检查材料思想汇报
2014/09/20 职场文书
Python排序算法之插入排序及其优化方案详解
2021/06/11 Python
Python机器学习实战之k-近邻算法的实现
2021/11/27 Python
为什么MySQL不建议使用SELECT *
2022/04/03 MySQL
win10以太网连接不上怎么办?Win10连接以太网详细教程
2022/04/08 数码科技
python中使用redis用法详解
2022/12/24 Redis