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数据库单表查询 4.3实验课
Apr 05 SQL Server
SQL SERVER中常用日期函数的具体使用
Apr 08 SQL Server
如何有效防止sql注入的方法
May 25 SQL Server
解决sql server 数据库,sa用户被锁定的问题
Jun 11 SQL Server
SQLServer 错误: 15404,无法获取有关 Windows NT 组/用户 WIN-8IVSNAQS8T7\Administrator 的信息
Jun 30 SQL Server
SQL写法--行行比较
Aug 23 SQL Server
sql时间段切分实现每隔x分钟出一份高速门架车流量
Feb 28 SQL Server
SQL Server数据库基本概念、组成、常用对象与约束
Mar 20 SQL Server
SQL Server的存储过程与触发器以及系统函数和自定义函数
Apr 10 SQL Server
SQL Server #{}可以防止SQL注入
May 11 SQL Server
SQL使用复合索引实现数据库查询的优化
May 25 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处理文件的小例子(解压缩,删除目录)
2013/02/03 PHP
Thinkphp的volist标签嵌套循环使用教程
2014/07/08 PHP
值得分享的php+ajax实时聊天室
2016/07/20 PHP
PHP实现双链表删除与插入节点的方法示例
2017/11/11 PHP
CI框架(CodeIgniter)实现的导入、导出数据操作示例
2018/05/24 PHP
Ajax+PHP实现的删除数据功能示例
2019/02/12 PHP
JavaScript 学习笔记(十四) 正则表达式
2010/01/22 Javascript
jQuery创建插件的代码分析
2011/04/14 Javascript
jQuery中jqGrid分页实现代码
2011/11/04 Javascript
一个简单的js树形菜单
2011/12/09 Javascript
jquery插件开发之实现google+圈子选择功能
2014/03/10 Javascript
Jquery仿IGoogle实现可拖动窗口示例代码
2014/08/22 Javascript
jquery实现简单的无缝滚动
2015/04/15 Javascript
js实现网站最上边可关闭的浮动广告条代码
2015/09/04 Javascript
jquery zTree异步加载、模糊搜索简单实例分享
2016/03/24 Javascript
JS简单测试循环运行时间的方法
2016/09/04 Javascript
JavaScript获取ul中li个数的方法
2017/02/13 Javascript
从零学习node.js之简易的网络爬虫(四)
2017/02/22 Javascript
vue写h5页面的方法总结
2019/02/12 Javascript
[06:23]2014DOTA2西雅图国际邀请赛 小组赛7月12日TOPPLAY
2014/07/12 DOTA
python将html转成PDF的实现代码(包含中文)
2013/03/04 Python
python将ansible配置转为json格式实例代码
2017/05/15 Python
python 调用win32pai 操作cmd的方法
2017/05/28 Python
Python探索之创建二叉树
2017/10/25 Python
python中logging包的使用总结
2018/02/28 Python
Python流行ORM框架sqlalchemy安装与使用教程
2019/06/04 Python
python读取目录下所有的jpg文件,并显示第一张图片的示例
2019/06/13 Python
Python小白学习爬虫常用请求报头
2020/06/03 Python
Spotahome意大利:公寓和房间出租
2020/02/21 全球购物
小学教师自我鉴定
2013/11/07 职场文书
迎新晚会策划方案
2014/06/13 职场文书
民间借贷协议书范本
2014/10/01 职场文书
主持人开幕词
2015/01/29 职场文书
居住证明范文
2015/06/17 职场文书
观后感的写法
2015/06/19 职场文书
学校2016年全国助残日活动总结
2016/04/01 职场文书