(Oracle)SQL优化案例:组合索引优化

项目场景

项目上的ETL模型里有如下SQL语句。执行速度非常慢,每次只查询200条数据,但却需要20多秒的时间。再加上该SQL查询出的数据同步频率很高,这个速度是完全不能忍受的。

因为项目隐私,所以对表及字段做了改写。

SELECT 
IDO.OD_SN
FROM IDO
LEFT JOIN IMO ON IMO.OD_SN= IDO.OD_SN
WHERE IMO.OD_TYPE IN ('X','Y')
AND IMO.SOURCE_ID IS NULL
AND IMO.MODIFY_TIME >= '20240423000000'
AND (IMO.YZ = 'N' OR IDO.YZ = 'N')
AND ROWNUM <= 200

IMO表的数据量:18134780行

IDO表的数据量:2908979行

上述SQL的结果集数量也很明显:200行 

问题分析

上面的SQL对于我等凡人来说,没办法一眼看出哪里有问题;所以还是需要拉一下执行计划(获取执行计划方法文章链接:获取执行计划)。

下面是问题SQL的执行计划,是已经将无关的信息删除。这里是获取的内存中shard_pool的执行计划,是真实的执行计划。

  • Plan hash value: 1275918432--------------------------------------------------------------------------------------------------------------------------------------------------------------
    | Id  | Operation                     | Name                      | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time   | A-Rows |   A-Time   | Buffers | Reads  |
    --------------------------------------------------------------------------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT              |                           |      1 |        |       |  2051 (100)|          |    100 |00:00:29.08 |    4057K|      1 |
    |*  1 |  COUNT STOPKEY                |                           |      1 |        |       |            |          |    100 |00:00:29.08 |    4057K|      1 |
    |   2 |   NESTED LOOPS                |                           |      1 |    102 |  6936 |  2051   (1)| 00:00:01 |    100 |00:00:29.08 |    4057K|      1 |
    |   3 |    NESTED LOOPS               |                           |      1 |    102 |  6936 |  2051   (1)| 00:00:01 |    100 |00:00:29.08 |    4056K|      1 |
    |*  4 |     TABLE ACCESS FULL         | IMO                       |      1 |  21724 |   954K|  1846   (1)| 00:00:01 |    100 |00:00:29.08 |    4056K|      0 |
    |*  5 |     INDEX UNIQUE SCAN         | UK_20230901211220_1065023 |    100 |      1 |       |     1   (0)| 00:00:01 |    100 |00:00:00.01 |     202 |      1 |
    |*  6 |    TABLE ACCESS BY INDEX ROWID| IDO                       |    100 |      1 |    23 |     2   (0)| 00:00:01 |    100 |00:00:00.01 |     100 |      0 |
    --------------------------------------------------------------------------------------------------------------------------------------------------------------Predicate Information (identified by operation id):
    ---------------------------------------------------1 - filter(ROWNUM<=100)4 - filter(("IMO"."MODIFY_TIME">='20240401000000' AND INTERNAL_FUNCTION("IMO"."OD_TYPE") AND "IMO"."SOURCE_ID" IS NULL))5 - access("IMO"."OD_SN"="IDO"."OD_SN")6 - filter((DECODE(TO_CHAR(SYS_OP_VECBIT("SYS_NC00279$",5)),NULL,NVL("IMO"."YZ",'N'),'0',NVL("IMO"."YZ",'N'),'1',"IMO"."YZ")='N' OR DECODE(TO_CHAR(SYS_OP_VECBIT("SYS_NC00155$",0)),NULL,NVL("IDO"."YZ",'N'),'0',NVL("IDO"."YZ",'N'),'1',"IDO"."YZ")='N'))

从上面的执行计划中,我们可以逐步分析:

  • 连接方式 (id=2、id=3)

IDO表和IMO表的连接方式是 NESTED LOOPS ,因为只返回少量数据(200行),所以走嵌套循环连接完全没问题。

  • 访问路径(id=4)

IMO表的访问路径是TABLE ACCESS FULL;上文已经提过,IMO表有18134780行数据,走全表扫描,还是返回少量数据;走全表扫描肯定是错误的

  • 访问路径(id=6)

IMO表的访问路径是TABLE ACCESS BY INDEX ROWID,索引ROWID扫描,没有问题。

  • 谓词信息

从谓词信息或者SQL语句中,我们可以发现IMO表中的MODIFY_TIME、SOURCE_ID、OD_TYPE字段中发生了谓词过滤。

从上面的信息,我们可以得出以下优化结论了:

Ⅰ:需要让IMO表走索引扫描;

Ⅱ:可以在IMO表上建立MODIFY_TIME、SOURCE_ID、OD_TYPE三个字段的组合索引;其中MODIFY_TIME的选择性最大,OD_TYPE的选择性其次,SOURCE_ID的选择性最差。所以选择MODIFY_TIME作为组合索引的先导列。

优化方案

创建组合索引

CREATE INDEX idx_mtime_type_source ON IMO (MODIFY_TIME,OD_TYPE,SOURCE_ID) ONLINE;

再次执行SQL,发现只需要0.1秒就可以执行完成。

我们此时再来看下执行计划,发现IMO表已经走了索引扫描;组合索引已经起到效果。

Plan hash value: 1019133023-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                                | Name                      | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time   | A-Rows |   A-Time   | Buffers | Reads  |
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                         |                           |      1 |        |       | 19528 (100)|          |    100 |00:00:00.02 |     401 |     49 |
|*  1 |  COUNT STOPKEY                           |                           |      1 |        |       |            |          |    100 |00:00:00.02 |     401 |     49 |
|   2 |   VIEW                                   | VW_ORE_7D109085           |      1 |    103 |  2060 | 19528   (1)| 00:00:01 |    100 |00:00:00.02 |     401 |     49 |
|   3 |    UNION-ALL                             |                           |      1 |        |       |            |          |    100 |00:00:00.02 |     401 |     49 |
|   4 |     NESTED LOOPS                         |                           |      1 |    102 |  6732 |   195   (0)| 00:00:01 |    100 |00:00:00.02 |     401 |     49 |
|*  5 |      TABLE ACCESS BY INDEX ROWID BATCHED | IMO                       |      1 |  21723 |   954K|    93   (0)| 00:00:01 |    100 |00:00:00.01 |     203 |     36 |
|*  6 |       INDEX RANGE SCAN                   | IDX_MTIME_TYPE_SOURCE     |      1 |  21744 |       |     5   (0)| 00:00:01 |    102 |00:00:00.01 |      10 |      9 |
|*  7 |      INDEX UNIQUE SCAN                   | UK_20230901211220_1065023 |    100 |      1 |    21 |     1   (0)| 00:00:01 |    100 |00:00:00.01 |     198 |     13 |
|   8 |     NESTED LOOPS                         |                           |      0 |      1 |    68 | 19332   (1)| 00:00:01 |      0 |00:00:00.01 |       0 |      0 |
|   9 |      NESTED LOOPS                        |                           |      0 |      1 |    68 | 19332   (1)| 00:00:01 |      0 |00:00:00.01 |       0 |      0 |
|* 10 |       TABLE ACCESS BY INDEX ROWID BATCHED| IMO                       |      0 |      1 |    45 | 19330   (1)| 00:00:01 |      0 |00:00:00.01 |       0 |      0 |
|* 11 |        INDEX RANGE SCAN                  | IDX_MTIME_TYPE_SOURCE     |      0 |  21744 |       |   608   (1)| 00:00:01 |      0 |00:00:00.01 |       0 |      0 |
|* 12 |       INDEX UNIQUE SCAN                  | UK_20230901211220_1065023 |      0 |      1 |       |     1   (0)| 00:00:01 |      0 |00:00:00.01 |       0 |      0 |
|* 13 |      TABLE ACCESS BY INDEX ROWID         | IDO                       |      0 |      1 |    23 |     2   (0)| 00:00:01 |      0 |00:00:00.01 |       0 |      0 |
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------Predicate Information (identified by operation id):
---------------------------------------------------1 - filter(ROWNUM<=100)5 - filter(DECODE(TO_CHAR(SYS_OP_VECBIT("SYS_NC00279$",5)),NULL,NVL("IMO"."YZ",'N'),'0',NVL("IMO"."YZ",'N'),'1',"IMO"."YZ")='N')6 - access("IMO"."MODIFY_TIME">='20240401000000' AND "IMO"."SOURCE_ID" IS NULL AND "IMO"."MODIFY_TIME" IS NOT NULL)filter((INTERNAL_FUNCTION("IMO"."OD_TYPE") AND "IMO"."SOURCE_ID" IS NULL))7 - access("IMO"."OD_SN"="IDO"."OD_SN")10 - filter(LNNVL(DECODE(TO_CHAR(SYS_OP_VECBIT("SYS_NC00279$",5)),NULL,NVL("IMO"."YZ",'N'),'0',NVL("IMO"."YZ",'N'),'1',"IMO"."YZ")='N'))11 - access("IMO"."MODIFY_TIME">='20240401000000' AND "IMO"."SOURCE_ID" IS NULL AND "IMO"."MODIFY_TIME" IS NOT NULL)filter((INTERNAL_FUNCTION("IMO"."OD_TYPE") AND "IMO"."SOURCE_ID" IS NULL))12 - access("IMO"."OD_SN"="IDO"."OD_SN")13 - filter(DECODE(TO_CHAR(SYS_OP_VECBIT("SYS_NC00155$",0)),NULL,NVL("IDO"."YZ",'N'),'0',NVL("IDO"."YZ",'N'),'1',"IDO"."YZ")='N')

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/2415.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

DaVinci Fusion Studio 19 for Mac/win:影视后期特效合成的巅峰之作

在影视后期制作的广袤天地里&#xff0c;一款强大的特效合成软件如同一位技艺高超的魔法师&#xff0c;能够化腐朽为神奇&#xff0c;将普通的影像素材转变为震撼人心的视觉盛宴。而DaVinci Fusion Studio 19&#xff0c;正是这样一款备受影视从业者推崇的巅峰之作。 无论是Ma…

基于Python+Selenium+Pytest的Dockerfile如何写

使用 Dockerfile 部署 Python 应用程序与 Selenium 测试 在本文中&#xff0c;我们将介绍如何使用 Dockerfile 部署一个 Python 应用程序&#xff0c;同时利用 Selenium 进行自动化测试。我们将使用官方的 Python 运行时作为父镜像&#xff0c;并在其中安装所需的依赖项和工具…

数据分析-pandas2

数据分析-pandas2 接上述1 计算同环比 我们之前讲过一个统计月度销售额的例子&#xff0c;我们可以通过groupby方法做分组聚合&#xff0c;也可以通过pivot_table生成透视表&#xff0c;如下所示。 sale_df pd.read_excel(r"./dates/2020年销售数据.xlsx") sale…

Android视角看鸿蒙第十二课-鸿蒙的布局之相对布局RelativeContainer

Android视角看鸿蒙第十二课-鸿蒙的布局之相对布局RelativeContainer 导读 相对布局和线性、层叠布局一样都是类似于Android布局的&#xff0c;之前两篇文章已经了解线性、层叠布局的使用方法&#xff0c;这篇文章一起来学习下鸿蒙中的相对布局。 之前的文章中&#xff0c;我偶…

算法开发固定三方库版本

步骤 先git clone想要的三方库&#xff0c;以yaml-cpp0.8为例根据readme进行cmake编译最后make install DESTDIR$YOUR_OUT_PATH 将编译产物放在指定目录内 三方库推荐工程目录架构 |–thirdparty |----yaml-cpp-0.8.0-aarch64 |----yaml-cpp-0.8.0-x86_64 CMakeLists.txt 指…

linux中新建一个超级管理员

新建一个管理员用户 admin useradd -u 0 -o admin u 用户号 指定用户的用户号&#xff1b;因为系统用户的用户号为 0&#xff0c;故指定用户号为 0&#xff1b; 如果同时有 -o 选项&#xff0c;则可以重复使用其他用户的标识号&#xff0c;因为系统本身存在用户号为 0 的系统用…

VNISEdit 制作安装包

1. 环境依赖 1.1. NSIS 下载 下载地址&#xff1a;https://nsis.sourceforge.io/Download 1.2. VNISEdit 下载 下载地址1&#xff1a;https://sourceforge.net/projects/hmne/ 下载 exe 安装。 下载地址2&#xff1a;https://hmne.sourceforge.net/ 可以下载 exe 安装。也…

centos 安装配置文件中心 nacos2.2.3 稳定版

安装mysql 8 参考文章 centos7搭建mysql5.6 && mysql 8.0_centos7 mysql5.6-CSDN博客 安装 jdk 17 官网下载 对应的版本 Java Downloads | Oracle wget https://download.java.net/java/GA/jdk17.0.2/dfd4a8d0985749f896bed50d7138ee7f/8/GPL/openjdk-17.0.2_l…

华纳云:怎么设计DDoS抵抗力强的网络架构?

设计DDoS抵抗力强的网络架构需要考虑多个方面&#xff0c;包括网络拓扑结构、硬件设备、流量过滤与监控等。以下是设计DDoS抵抗力强的网络架构的一些建议&#xff1a; 分布式架构&#xff1a; 将网络架构设计为分布式的结构&#xff0c;通过多个地理位置的数据中心和服务器分散…

在excel中,如何在一个表中删除和另一个表中相同的数据?

现在有A表&#xff0c;是活动全部人员的姓名和学号&#xff0c;B表是该活动中获得优秀人员的姓名和学号&#xff0c; 怎么提取没有获得优秀人员的名单&#xff1f; 这里提供两个使用excel基础功能的操作方法。 1.条件格式自动筛选 1.1按住Ctrl键&#xff0c;选中全表中的姓…

s AbortController 接口取消多次请求 取消上次请求

AbortController 是一个 JavaScript API&#xff0c;它允许您在客户端中止一个或多个 Fetch 请求。这个 API 是 Fetch API 的一部分&#xff0c;并且与 AbortSignal 对象一起使用&#xff0c;以提供一种机制来控制请求的生命周期。 以下是 AbortController 的基本用法&#xf…

Flutter 上架如何解决 ITMS-91053 问题

最近&#xff0c;我的 Flutter App 发布到 TestFlight 后&#xff0c;就会收到一封邮件&#xff1a;The uploaded build for YOUR APP has one or more issues. 上面的邮件主要是说&#xff0c;我的 App 缺少了调用 API 的声明&#xff0c;以前从来没看到过&#xff0c;上网一查…

SpringBoot+Vue开发记录(三)

说明&#xff1a;本篇文章的主要内容为需求分析。需求分析这一部分很重要&#xff0c;也稍微有点子难搞&#xff0c;所以本篇文章里的有些内容会有失偏颇。 一、准备步骤 我打算做一个刷题项目&#xff0c;但是具体这个项目该怎么做&#xff0c;我是一头雾水。 所以就要先进行…

消灭AI“耗电巨兽”?暴雨服务器推出液冷节能降耗算力方案

在科技飞速发展的今天&#xff0c;人工智能已成为驱动未来的重要力量。随着AI及大模型技术的进一步普及和应用场景的拓宽&#xff0c;相关算力需求呈指数级增长&#xff0c;大规模的AI训练和推理过程均需消耗大量电力&#xff0c;如同一个巨大的电力黑洞&#xff0c;吞噬着海量…

spring boot的项目+nginx,怎么预防点击劫持(clicekJacking)

点击劫持&#xff08;Clickjacking&#xff09;是一种视觉欺骗技术&#xff0c;攻击者通过在透明的框架上叠加一个看似无害的界面&#xff0c;诱使用户在不知情的情况下点击按钮或链接&#xff0c;从而执行攻击者意图的操作。为了防御点击劫持攻击&#xff0c;在结合Spring Boo…

【k8s】(八)kubernetes1.29.4离线部署之-测试验证

&#xff08;一&#xff09;kubernetes1.29.4离线部署之-安装文件准备 &#xff08;二&#xff09;kubernetes1.29.4离线部署之-镜像文件准备 &#xff08;三&#xff09;kubernetes1.29.4离线部署之-环境初始化 &#xff08;四&#xff09;kubernetes1.29.4离线部署之-组件安装…

Elasticsearch集群部署(Linux)

1. 准备环境 这里准备三台Linux虚拟机&#xff0c;用于配置Elasticsearch集群和部署可视化工具Kibana。 角色IP域名集群名称节点名称版本操作系统ES192.168.243.100linux100cluster-eses-node-1007.12.0CentOS 7192.168.243.101linux101cluster-eses-node-101192.168.243.102…

docker容器内彻底移除iptables服务的实现方法

背景 我创建的容器使用的是centos6的标准镜像&#xff0c;所以内置了iptables服务。容器启动后iptables服务默认就启动了。iptables设置的规则默认是所有流量都无法通行。而对于服务器的管理使用的是宿主机的防火墙。这样就导致在实现用iptables动态给容器添加端口映射时不成功…

coredns部署

coredns部署 coredns部署 一&#xff1a;coredns-rbac.yaml apiVersion: v1 kind: ServiceAccount metadata:name: corednsnamespace: kube-systemlabels:kubernetes.io/cluster-service: "true"addonmanager.kubernetes.io/mode: Reconcile --- apiVersion: rbac…

如何对同一docker注册表使用多个身份验证/登录

常用容器登录方式 # 公共变量 REGISTRY"registry.cn-chengdu.aliyuncs.com"new_docker_username"root" new_docker_password"password" # 登录新的Docker账号 docker login -u "$new_docker_username" -p "$new_docker_password…