oracle性能优化(项目中的一个sql优化的简单记录)

在项目中,写的sql主要以查询为主,但是数据量一大,就会突出sql性能优化的重要性。其实在数据量2000W以内,可以考虑索引,但超过2000W了,就要考虑分库分表这些了。本文主要记录在实际项目中,一个需要查询很慢的sql的优化过程,如果有更好的方案,请在下面留言交流。

很多文章都有关于sql优化的方法,这里就不一一陈述了。如果有需要可以查看博客:https://blog.csdn.net/linhaiyun_ytdx/article/details/79101122

SELECT T.YHBH,
       (SELECT NAME FROM DIM_REGION WHERE CODE = SUBSTR(T.GDDWBM, 0, 4)) GDDWMC,
       (SELECT NAME FROM DIM_REGION WHERE CODE = T.GDDWBM) FJMC,
       T.DFNY,
       T.YHMC,
       T.YDDZ,
       (SELECT NAME FROM DIM_ELECTRICITY_TYPE WHERE CODE = T.YHLBDM) YDLBMC
  FROM (SELECT DISTINCT T.YHBH,
                        DECODE(T.GDDWBM,
                               NULL,
                               ‘0000‘,
                               DECODE(T.GDDWBM, ‘09‘, ‘0000‘, T.GDDWBM)) AS GDDWBM,
                        T.BBNY AS DFNY,
                        T.YHLBDM AS YHLBDM,
                        T.YHMC,
                        T2.YDDZ
          FROM V_TEMP_TABLE_JHCBHSTJ_HISTORY T, TMP_KH_YDKH T2
         WHERE T.YHBH = T2.YHBH(+)
           AND NOT EXISTS (SELECT 1
                  FROM DJHJSL_LSB_FZ_HISTORY B
                 WHERE B.BBNY = T.BBNY
                   AND B.YHBH = T.YHBH
                   AND B.GDDWBM = T.GDDWBM
                   AND B.YHLBDM = T.YHLBDM
                   AND B.ZDCBZHS <> ‘0‘)
) T
WHERE SUBSTR(T.GDDWBM, 0, 4) = ‘0946‘
  AND T.DFNY = ‘201911‘

这个是我的sql脚本。其实这个脚本一点都不复杂。其中V_TEMP_TABLE_JHCBHSTJ_HISTORY,DJHJSL_LSB_FZ_HISTORY每个月增加330万,目前有1960多万, TMP_KH_YDKH表有330多万。DIM_REGION 和DIM_ELECTRICITY_TYPE 是两个数据字典项表。

在没有索引的情况下,这个脚本执行需要30s,看到执行过程,现在都是全表扫描的。接下来开始优化。

1.修改脚本的查询,将外层的查询条件放到里面,减少数据量。

SELECT T.YHBH,
       (SELECT NAME FROM DIM_REGION WHERE CODE = SUBSTR(T.GDDWBM, 0, 4)) GDDWMC,
       (SELECT NAME FROM DIM_REGION WHERE CODE = T.GDDWBM) FJMC,
       T.DFNY,
       T.YHMC,
       T.YDDZ,
       (SELECT NAME FROM DIM_ELECTRICITY_TYPE WHERE CODE = T.YHLBDM) YDLBMC
  FROM (SELECT DISTINCT T.YHBH,
                        DECODE(T.GDDWBM,
                               NULL,
                               ‘0000‘,
                               DECODE(T.GDDWBM, ‘09‘, ‘0000‘, T.GDDWBM)) AS GDDWBM,
                        T.BBNY AS DFNY,
                        T.YHLBDM AS YHLBDM,
                        T.YHMC,
                        T2.YDDZ
          FROM V_TEMP_TABLE_JHCBHSTJ_HISTORY T, TMP_KH_YDKH T2
         WHERE T.YHBH = T2.YHBH(+)
           AND NOT EXISTS (SELECT 1
                  FROM DJHJSL_LSB_FZ_HISTORY B
                 WHERE B.BBNY = T.BBNY
                   AND B.YHBH = T.YHBH
                   AND B.GDDWBM = T.GDDWBM
                   AND B.YHLBDM = T.YHLBDM
                   AND B.ZDCBZHS <> ‘0‘)
            AND SUBSTR(T.GDDWBM, 0, 4) = ‘0946‘
            AND T.BBNY = ‘201911‘
) T 

2.对三个表都建上索引

对V_TEMP_TABLE_JHCBHSTJ_HISTORY根据DFNY,SUBSTR(T.GDDWBM, 0, 4)建上联合索引。

CREATE INDEX IDX_TMP_JHCBHSTJ_HISTORY_UNION ON V_TEMP_TABLE_JHCBHSTJ_HISTORY(BBNY,SUBSTR(GDDWBM, 0, 4));

对TMP_KH_YDKH表,使用了关联,所以需要对yhbh建个索引

create index IDX_YHBH_KH on TMP_KH_YDKH (YHBH);

对于DJHJSL_LSB_FZ_HISTORY表,在not EXISTS里面,会全表扫描这个表,现在对他建立联合索引试试。

CREATE INDEX IDX_DJHJSL_FZ_HISTORY_UNION ON V_TEMP_TABLE_JHCBHSTJ_HISTORY(BBNY,YHBH,GDDWBM,YHLBDM);

查看oracle的执行计划,建立联合索引,并没有让这个表走索引,还是在全表扫描的,但是查询已经提升到9s了。

接下来对分别对这四个字段建立索引:

create index IDX_DJHJSL_FZ_HISTORY_BBNY on DJHJSL_LSB_FZ_HISTORY (BBNY);
create index IDX_DJHJSL_FZ_HISTORY_YHBH on DJHJSL_LSB_FZ_HISTORY (YHBH);
create index IDX_DJHJSL_FZ_HISTORY_GDDWBM on DJHJSL_LSB_FZ_HISTORY (GDDWBM);
create index IDX_DJHJSL_FZ_HISTORY_YHLBDM on DJHJSL_LSB_FZ_HISTORY (YHLBDM);

从执行计划来看,oracle只走了IDX_DJHJSL_FZ_HISTORY_BBNY这个索引,现在最快已经到1.95s了。

虽然现在已经满足了查询3s内的要求,但是考虑到以后,每个月的数据增长,数据量有5000万,一亿这样的大数据量的时候还是会很慢。

其实我在正式环境测试的时候,NOT EXISTS 里面的这个表,建立单个索引是没有用的,建立联合索引才会使这个表走索引,可能是因为电脑的cpu不同等因素影响的。

上面的优化方法当然不能满足项目的需求,接下来结合业务进行优化。作为一个监控系统,数据是T+1的,不需要追求实时性,这些数据,都是使用etl抽取工具每天定时抽取的。而且每个月300万数据,用户只关注的只有几千条。所以结合业务,我们在使用etl抽取完数据后,将用户关注的数据插入到另一张表中,这样,每个月只有几千条数据,这样的话,一年也才几万条数据,对oracle来说决定是零压力的。

如果大家还有其他的方式优化,请在下方留言交流。

原文地址:https://www.cnblogs.com/pluto-charon/p/11964776.html

时间: 2024-10-12 07:25:38

oracle性能优化(项目中的一个sql优化的简单记录)的相关文章

maven新建Spring MVC + MyBatis + Oracle的Web项目中pom.xml文件

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion&

Java项目中每一个类都可以有一个main方法

Java项目中每一个类都可以有一个main方法,但只有一个main方法会被执行,其他main方法可以对类进行单元测试. public class StaticTest { public static void main(String[] args) { Employee[] staff=new Employee[3]; staff[0]=new Employee("Tom",40000); staff[1]=new Employee("Dick",60000); s

实际项目中的一个实例

/* * map.cpp * * Created on: 2014-8-20 * Author: shopping */ #include <stdio.h> #include <utility> #include <list> #include <map> /*1. 定义一个函数指针*/ typedef void * (* pCreateFun)() ; /*2. 定义一个pair*/ typedef std::pair<char * ,pCreat

记录一个sql优化后大大提高查询效率的情形

众所周知,sql写得怎么样,对于查询效率的影响是颇大的.下面看一个比较普通的查询: 假设一张表有event_date和event_time2个字段分别表示日期和时间,现在直接给你一个时间字符串,这个时间字符串是“日期+时间”的组合,现在需要按时间范围过滤出一部分数据.如果你不转弯的话,很有可能你会按照惯性思维使用concat(event_date, event_time)连接函数,如: SELECT A, MAX(B) AS B,SUBSTR(CONCAT(event_date, event_t

项目中常用的SQL语句

摘要: 对于像我一样的菜鸟级别人物来说,接触的项目比较少,平常做的那些练习,包括三层中,一般也只能用到增删改查,当然这些增删改查语句是学数据库语句的入门,在百度上搜索一大堆,w3cschool中帮助文档也可以查阅. 这里是把平常用的增删改做一个小小总结,对一些小小项目也是比较适用的 ,当然,好记性不如烂笔头吗,这个时代纸质版的笔记感觉很欠缺,因为想要看的时候,你得找到那本书,而且要翻翻在哪里,感觉很不方便.并且电子版 的随便copy之类的都可以. 常用的sql语句(增删改查) 1.增加.插入语句

项目总结二:关于项目中一些功能的优化

前言: 最近一直在维护老的项目,遇到的问题也千奇百怪,需要修补的,需要优化的,需要特殊处理的,感觉总是那么的无语.也许这时候也应该感叹一句:路漫漫其修远兮,吾将上下而求索吧. 这篇文章就只是讲讲老项目中遇到的种种不敢苟同的代码写法,以及遇到一些问题时的处理方法. 1.关于按钮事件的重复点击问题 我们开发中大概都经历过这样的事情,我的一个button被重复的快速点击,(我们开发者应该更清楚的知道这意味着什么).那我们再深入的想一下(给这样的事件安排一个特定的环境):例如当网络较差的情况下,再例如当

在web项目中搭建一个spring mvc + spring + mybatis的环境

介绍:本文中示范搭建一个ssm环境的框架:使用流程就是客户端通过http请求访问指定的接口,然后由服务器接受到请求处理完成后将结果返回. 本项目请求流程细节介绍:由客户端请求到指定的接口,这个接口是个jsp的页面,在jsp页面中会自动请求jsp中指定的接口,请求到达comcat服务器后由spring mvc提供的DispatchServlet类进行接受,然后将请求交给HandierMapping接口的实现类去解析当前请求的所有参数,再交给HandlerAdaper接口的实现类去将所有参数和对象(

在vue项目中添加一个html页面,开启本地服务器

在vue项目里新增一个不需要登录的页面,那么我只能新增一个html页面了,不经过路由,直接在浏览器输入路径打开,那么就需要用到本地服务器, 1.vue里面的html页面最好放过在public文件夹里面,但是我的vue项目没有public,就只好放在static里面了,这样可以不经过vue的路由 2.然后就是开本地服务器,当然,是基于node的, 1)可以在这里下载 https://nodejs.org,安装完成后可以在控制台输入:node -v 查看版本号 2)下载http-server:在控制

组装者模式在React Native项目中的一个实战案例

前言 在实际的开发中,如果遇到多个组件有一些共性,我们可以提取一个BaseItem出来,然后在多个组件中进行复用,一种方式是通过继承的方式,而今天我们要说的是另一种方式--组装者模式. 什么是组装者模式? 就是在一个类中封装一些共有特性,然后使得在使用的组件中,可以动态的去添加一些属性或者行为,相比较于继承来说,组装者模式会更加的灵活. 实例演示 /** * AboutCommon.js * 组装者模式 模仿一些生命周期函数 */ export default class AboutCommon