联系生活来简化sql(r3笔记第43天)
时间:2022-05-04
本文章向大家介绍联系生活来简化sql(r3笔记第43天),主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
目前生产环境中有一条sql语句的CPU消耗很高。执行时间比较长。从awr中抓到的sql语句如下:
SELECT run_request.run_mode, cycle_groups.flow_id,
cycle_groups.request_id, cycle_groups.dynamic_attributes,
cycle_groups.sys_creation_date, cycle_groups.sys_update_date,
cycle_control.cycle_code
FROM (SELECT cycle_groups.*, a.request_id
FROM (SELECT cycle_groups.GROUP_ID,
cycle_groups.flow_id,
cycle_groups.cycle_seq_no,
cycle_groups.route,
group_status.request_id
FROM cycle_groups, --数据量在1万左右
group_status --数据量在百万
WHERE cycle_groups.GROUP_ID =group_status.GROUP_ID --这些都是索引列
AND cycle_groups.flow_id = group_status.flow_id --这些都是索引列
AND cycle_groups.cycle_seq_no =group_status.cycle_seq_no
AND cycle_ghttp://blog.itpub.net/23718752/viewspace-1317283/roups.route = group_status.route
GROUP BY cycle_groups.GROUP_ID,
cycle_groups.flow_id,
cycle_groups.cycle_seq_no,
cycle_groups.route,
group_status.request_id) a,
cycle_groups
WHERE cycle_groups.GROUP_ID = a.GROUP_ID --这个地方又关联了一次
AND cycle_groups.flow_id = a.flow_id
AND cycle_groups.cycle_seq_no = a.cycle_seq_no
AND cycle_groups.route = a.route) cycle_groups,
cycle_control,
run_request
WHERE cycle_groups.status = 'FIN'
AND cycle_groups.request_id = run_request.request_id
AND cycle_control.cycle_seq_no = cycle_groups.cycle_seq_no
AND cycle_control.cycle_code
|| '_'
|| cycle_groups.flow_id
|| '_'
|| run_request.run_mode IN (
SELECT cycle_control.cycle_code
|| '_'
|| run_request.flow_id
|| '_'
|| run_request.run_mode
FROM run_request, cycle_control
WHERE ( run_request.population_type = 'CYC'
OR run_request.population_type = 'CCD'
)
AND run_request.population_id =cycle_control.cycle_seq_no)
ORDER BY cycle_groups.request_id
从第一印象来看,sql语句有些臃肿,过滤条件也比较奇怪。 首先是标黄的部分,关联的连接条件都是索引列. 执行计划如下,可以看到还是消耗很大的。
--------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time | Pstart| Pstop |
------------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | | 273K(100)| | | |
| 1 | SORT ORDER BY | | 5714K| 1111M| 1174M| 273K (1)| 00:54:46 | | |
|* 2 | HASH JOIN | | 5714K| 1111M| | 19993 (1)| 00:04:00 | | |
| 3 | VIEW | VW_NSO_1 | 423 | 13959 | | 28 (11)| 00:00:01 | | |
| 4 | HASH UNIQUE | | 423 | 12690 | | 28 (11)| 00:00:01 | | |
|* 5 | HASH JOIN | | 6992 | 204K| | 26 (4)| 00:00:01 | | |
| 6 | VIEW | index$_join$_009 | 2157 | 17256 | | 3 (34)| 00:00:01 | | |
|* 7 | HASH JOIN | | | | | | | | |
| 8 | INDEX FAST FULL SCAN | CYCLE_CONTROL_PK | 2157 | 17256 | | 1 (0)| 00:00:01 | | |
| 9 | INDEX FAST FULL SCAN | CYCLE_CONTROL_1IX | 2157 | 17256 | | 1 (0)| 00:00:01 | | |
|* 10 | TABLE ACCESS FULL | RUN_REQUEST | 7641 | 164K| | 23 (0)| 00:00:01 | | |
|* 11 | HASH JOIN | | 1350K| 220M| | 19944 (1)| 00:04:00 | | |
| 12 | TABLE ACCESS FULL | RUN_REQUEST | 7735 | 92820 | | 23 (0)| 00:00:01 | | |
|* 13 | HASH JOIN | | 1350K| 204M| | 19916 (1)| 00:03:59 | | |
| 14 | JOIN FILTER CREATE | :BF0000 | 12436 | 1590K| | 70 (2)| 00:00:01 | | |
|* 15 | HASH JOIN | | 12436 | 1590K| | 70 (2)| 00:00:01 | | |
| 16 | VIEW | index$_join$_006 | 2157 | 17256 | | 3 (34)| 00:00:01 | | |
|* 17 | HASH JOIN | | | | | | | | |
| 18 | INDEX FAST FULL SCAN| CYCLE_CONTROL_PK | 2157 | 17256 | | 1 (0)| 00:00:01 | | |
| 19 | INDEX FAST FULL SCAN| CYCLE_CONTROL_1IX | 2157 | 17256 | | 1 (0)| 00:00:01 | | |
|* 20 | TABLE ACCESS FULL | CYCLE_GROUPS | 13072 | 1570K| | 67 (0)| 00:00:01 | | |
| 21 | VIEW | | 1426K| 38M| | 19840 (1)| 00:03:59 | | |
| 22 | HASH GROUP BY | | 1426K| 69M| 87M| 19840 (1)| 00:03:59 | | |
| 23 | JOIN FILTER USE | :BF0000 | 1426K| 69M| | 1746 (1)| 00:00:21 | | |
| 24 | NESTED LOOPS | | 1426K| 69M| | 1746 (1)| 00:00:21 | | |
| 25 | PARTITION RANGE ALL | | 1426K| 38M| | 1740 (1)| 00:00:21 | 1 | 19 |
| 26 | INDEX FULL SCAN | GROUP_STATUS_PK | 1426K| 38M| | 1740 (1)| 00:00:21 | 1 | 19 |
|* 27 | INDEX UNIQUE SCAN | CYCLE_GROUPS_PK | 1 | 23 | | 1 (0)| 00:00:01 | | |
------------------------------------------------------------------------------------------------------------------------------
这个调优可以从一个生活的例子来简单说明。 我平时早餐吃面包,就举吃面包的例子吧。 比如我在所住的校区门口有家面包店,每次我买面包都会得到一个收据,上面有所买的面包明细和卡号,还有一个流水号。 在公司楼下也有一个面包店,都可以用同一张卡来消费,也会得到一个流水号。 可以关联起来,表cycle_groups就类似一个客户清单,清单中的每一项就代表一个客户卡号。而表group_status就代表消费的明细,比如流水号,所卖的面包和所消费的金额时间等。 cycle_group里只有卡号等信息,在cycle_status中是消费的数据。 这个时候我们想得到某张卡号 消费的情况,比如卡号,年月日,消费的金额,如果流水号相同只输出一个流水号。 这个操作就类似下面的形式。
SELECT cycle_groups.GROUP_ID,
cycle_groups.flow_id,
cycle_groups.cycle_seq_no,
cycle_groups.route,
group_status.request_id
FROM cycle_groups, --数据量在1万左右
group_status --数据量在百万
WHERE cycle_groups.GROUP_ID =group_status.GROUP_ID --这些都是索引列
AND cycle_groups.flow_id = group_status.flow_id --这些都是索引列
AND cycle_groups.cycle_seq_no =group_status.cycle_seq_no
AND cycle_groups.route = group_status.route
GROUP BY cycle_groups.GROUP_ID,
cycle_groups.flow_id,
cycle_groups.cycle_seq_no,
cycle_groups.route,
group_status.request_id
而这个时候我们得到了一个卡号,消费年月日,消费流水号的清单,流水号相同的情况下,可以只得到50万条记录。 这个时候我们想给予目前的统计结果,得到卡号,消费的门店,消费金额,消费流水号时,这个时候就相当于根据流水号把表cycle_status里面的数据又重新查取了一遍。 这个时候你想想,还不如直接关联卡号和消费记录来查取一次呢。因为,在子查询里过滤了流水号,只显示一条不重复的流水号,但是外部查询中又需要得到更为详细的信息,导致过滤了一次数据,然后又重新还原了一遍。
SELECT cycle_groups.*, a.request_id
FROM (SELECT cycle_groups.GROUP_ID,
cycle_groups.flow_id,
cycle_groups.cycle_seq_no,
cycle_groups.route,
group_status.request_id
FROM cycle_groups, --数据量在1万左右
group_status --数据量在百万
WHERE cycle_groups.GROUP_ID =group_status.GROUP_ID --这些都是索引列
AND cycle_groups.flow_id = group_status.flow_id --这些都是索引列
AND cycle_groups.cycle_seq_no =group_status.cycle_seq_no
AND cycle_groups.route = group_status.route
GROUP BY cycle_groups.GROUP_ID,
cycle_groups.flow_id,
cycle_groups.cycle_seq_no,
cycle_groups.route,
group_status.request_id) a,
cycle_groups
WHERE cycle_groups.GROUP_ID = a.GROUP_ID --这个地方又关联了一次
AND cycle_groups.flow_id = a.flow_id
AND cycle_groups.cycle_seq_no = a.cycle_seq_no
AND cycle_groups.route = a.route
所以可能自己想了很多的思路,但是最后还是又把问题回归到原点。
- Common Service Locator library
- 源码解读bucket 删除中的一些细节
- 论Spark Streaming的数据可靠性和一致性
- RGW 的GC深入解析与调优
- 大数据查询——HBase读写设计与实践
- 基于Logstash的自动化运维系统实现
- 简谈RGW的index shard计算
- Blackpearl 的 Impersonate
- SparkMLLib中基于DataFrame的TF-IDF
- 运用Python实现WordPress网站大规模自动化发布文章
- 基于java的中文分词工具ANSJ
- 基于DF的Tokenizer分词
- 基于pyenv和virtualenv搭建python多版本虚拟环境
- 基于DataFrame的StopWordsRemover处理
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 介绍一个可以离线查询 IP 来源和 ISP 信息的终端利器
- 这也太简单了吧!一个函数完成数据相关性热图计算和展示
- CentOS7安装Zookeeper
- CentOS7卸载OpenJDK,然后安装Oracle JDK
- Java停止线程的四种方法
- Educational Codeforces Round 95 (Rated for Div. 2) A-D
- Go服务迁到K8s后老抽风重启? 记一次完整的线上问题解决过程
- PHP的另一个高效缓存扩展:Yac
- 在PHP中操作临时文件
- 在线IDE开发入门之从零实现一个在线代码编辑器
- 树莓派4裸机基础教程:从hello world开始
- 基于f2从零实现移动端可视化编辑器
- GORM V2 读操作
- Kubernetes 1.19.0——Pod(1)
- GORM V2 写操作