当前位置: 首页 > news >正文

【SQL优化案例】索引创建不合理导致SQL消耗大量CPU资源

#隐式转换 

第一章 适用环境

  • oracle 11g+
  • linux 6.9+

第二章 Top SQL概况

下面列出我们发现的特定模块中Top SQL的相关情况:

SQL_ID

模块

SQL类型

主要问题

fnc58puaqkd1n

select

索引创建不合理,导致全索引扫描,产生了大量逻辑读

第三章 SQL优化方案

3.1 SQL_ID:fnc58puaqkd1n

3.1.1 SQL文本

SELECT MAX(TEST_ID) TEST_ID FROM TEST1 WHERE TEST_NAME = 28                                                

3.1.2 SQL执行计划

PLAN_TABLE_OUTPUT                                                                                                                                                                                       
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID  fnc58puaqkd1n, child number 0                                                                                                                                                                   
-------------------------------------                                                                                                                                                                   
SELECT MAX(TEST_ID) TEST_ID FROM TEST1 WHERE TEST_NAME = 28                                                                                                                                     Plan hash value: 2527920730                                                                                                                                                                             ---------------------------------------------------------------------------------------------------                                                                                                     
| Id  | Operation             | Name                      | Rows  | Bytes | Cost (%CPU)| Time     |                                                                                                     
---------------------------------------------------------------------------------------------------                                                                                                     
|   0 | SELECT STATEMENT      |                           |       |       | 23200 (100)|          |                                                                                                     
|   1 |  SORT AGGREGATE       |                           |     1 |    13 |            |          |                                                                                                     
|*  2 |   INDEX FAST FULL SCAN| TEST1_TEST_ID_IDX         |     1 |    13 | 23200   (3)| 00:04:39 |                                                                                                     
---------------------------------------------------------------------------------------------------                                                                                                     Predicate Information (identified by operation id):                                                                                                                                                     
---------------------------------------------------                                                                                                                                                     2 - filter(TO_NUMBER("TEST_NAME")=28)     

3.1.3 SQL资源消耗

            CPU(MS)  ELA(MS)     DISK          GET        ROWS      ROWS APPLI(MS) CONCUR(MS) CLUSTER(MS) USER_IO(MS)    PLSQL     JAVA                                                                 
EXEC       PRE EXEC PRE EXEC PRE EXEC     PRE EXEC    PRE EXEC PRE FETCH  PER EXEC   PER EXEC    PER EXEC    PER EXEC PER EXEC PER EXEC SQL_PROFILE                                                     
---------- -------- -------- -------- ------------ ----------- --------- --------- ---------- ----------- ----------- -------- -------- ---------------                                                 
2887          2,116    2,146        0       89,108           1         1         0          0           0           0        0        0                                                                 

该SQL执行了2887次,每次执行的平均逻辑读为89,108,物理读为0,每次返回1条数据,耗时2.146秒,其中CPU消耗2.116秒。

四、 问题分析及优化思路

通过分析SQL文本,发现该SQL为单表扫描类型,select涉及max函数。

通过分析执行计划,SQL主要性能消耗在TEST1_TEST_ID_IDX 的全索引扫描,该索引的体积达到705MB,由于该SQL执行频率高达2887次,等待主要在CPU上,这就是该SQL执行耗时只有2秒原因。

那为什么会导致该SQL走的是快速索引全扫描,而不是索引范围扫描?观察到执行计划中有一个隐式转换,是它的原因吗?通过测试发现并不是。那问题在哪?

再看下TEST1_TEST_ID_IDX组成列的顺序是TEST_ID、TEST_NAME,而SQL的过滤条件是TEST_NAME,针对TEST_ID算MAX值,到这里问题就清楚了,索引创建的顺序有问题,前导列应该是TEST_NAME,正确的索引创建顺序应该是TEST_NAME、TEST_ID,让执行计划走MAX/MIN类型。

另外还有一个问题,该SQL存在隐式转换,观察到TEST_NAME字段类型是varchar2,而SQL传值类型是数值,如果不消除这个问题,有正确的索引仍然无法走最优的执行计划。

结合以上分析,该SQL需要消除隐式转换,再创建合适的索引即可优化。

五、 优化方案

5.1 创建组合索引

CREATE INDEX "TESTUSER"."TEST1_N1" ON "TESTUSER"."TEST1" (TEST_NAME,TEST_ID) tablespace TESTUSER_IDX  online;

5.2 查看索引效果

SQL> SELECT MAX(TEST_ID) TEST_ID FROM TESTUSER.TEST1 WHERE TEST_NAME = 28;Execution Plan
----------------------------------------------------------
Plan hash value: 3698544155------------------------------------------------------------------------------------------
| Id  | Operation             | Name             | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT      |                  |     1 |    13 | 13251   (3)| 00:02:40 |
|   1 |  SORT AGGREGATE       |                  |     1 |    13 |            |          |
|*  2 |   INDEX FAST FULL SCAN| TEST1_N1         |  1075K|    13M| 13251   (3)| 00:02:40 |
------------------------------------------------------------------------------------------Predicate Information (identified by operation id):
---------------------------------------------------2 - filter(TO_NUMBER("TEST_NAME")=28)

观察仍然走的TEST1_N1索引INDEX FAST FULL SCAN。有两种方案可以解决,一是创建函数索引,二是修改传参类型,这里我们选择改传参类型。

5.3 优化后的效果

SQL> SELECT MAX(TEST_ID) TEST_ID FROM TESTUSER.TEST1 WHERE TEST_NAME = '28';Execution Plan
----------------------------------------------------------
Plan hash value: 1923666499-------------------------------------------------------------------------------------------------
| Id  | Operation                    | Name             | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |                  |     1 |    13 |     3   (0)| 00:00:01 |
|   1 |  SORT AGGREGATE              |                  |     1 |    13 |            |          |
|   2 |   FIRST ROW                  |                  |     1 |    13 |     3   (0)| 00:00:01 |
|*  3 |    INDEX RANGE SCAN (MIN/MAX)| TEST1_N1         |     1 |    13 |     3   (0)| 00:00:01 |
-------------------------------------------------------------------------------------------------Predicate Information (identified by operation id):
---------------------------------------------------3 - access("TEST_NAME"='28')

六、 优化效果对比

通过确认关键表数据量,制定执行计划,可以减少每次查询的逻辑读和物理读,提高SQL执行性能。

逻辑读

物理读

执行时间(s)

优化前

89,108

0

2.3

优化后

3

0

0.01


🚀 更多数据库干货,欢迎关注【安呀智数据坊】

如果你觉得这篇文章对你有帮助,欢迎点赞 👍、收藏 ⭐ 和留言 💬 交流,让我知道你还想了解哪些数据库知识!

📬 想系统学习更多数据库实战案例与技术指南?

📊 实战项目分享

📚 技术原理讲解

🧠 数据库架构思维

🛠 工具推荐与实用技巧

立即关注,持续更新中 👇

http://www.xdnf.cn/news/1076329.html

相关文章:

  • SpringBoot - 定时任务改Cron不重启,调度规则生效
  • RuoYi-Vue前后端分离版实现前后端合并
  • 用Fiddler中文版抓包工具掌控微服务架构中的接口调试:联合Postman与Charles的高效实践
  • docker desktop部署本地gitlab服务
  • 学习昇腾开发的第12天--安装第三方依赖
  • 基于springboot的养老院管理系统
  • LINUX2.6设备注册与GPIO相关的API
  • Vue3 中 Excel 导出的性能优化与实战指南
  • JavaScript 安装使用教程
  • ip网络基础
  • FastGPT与MCP:解锁AI新时代的技术密码
  • 百度轮岗:任命新CFO,崔珊珊退居业务二线
  • 使用Electron开发跨平台RSS阅读器:从零到一的完整指南
  • Linux查看空间大小相关命令内容
  • 数据结构复习4
  • 前端计算机视觉:使用 OpenCV.js 在浏览器中实现图像处理
  • Oracle 常用函数
  • 38.docker启动python解释器,pycharm通过SSH服务直连
  • 【软考高项论文】论信息系统项目的进度管理
  • Zookeeper安装使用教程
  • SQL规范
  • IDEA相关配置记录
  • 【中文核心期刊推荐】《计算机应用与软件》
  • Windows CMD命令分类大全
  • 前端开发面试题总结-原生小程序部分
  • 衡石科技使用手册-企业即时通讯工具数据问答机器人用户手册
  • STM32要学到什么程度才算合格?
  • 华为云Flexus+DeepSeek征文|基于 Dify-LLM 构建网站智能客服助手的实践探索
  • Go语言安装使用教程
  • C++ 快速回顾(五)