大罗讲SQL:如何优雅的进行SQL编写?
墨墨导读:SQL可以写的很笨重,也可以写的很优雅,本文从一个简单的查询v$SQL/DBA_HIST_SQLSTAT的语句开始,介绍几种常用的优雅SQL编写方式。
在分析v$sql 或者 dba_hist_sqlstat的时候,由于时常需要计算单次执行的相关指标,目前看到多数人用的是类似这样的写法
elapsed_time / CASE WHEN executions = 0THEN 1ELSE executionsEND
或者
elapsed_time / decode(executions,0,1,executions)
目的是避免executions(或者executions_delta)为0时导致除数为0的错误。不能说这样写有错,但是不够优雅。优雅的做法是什么呢?应该是使用greatest函数,写法是:
elapsed_time /greatest(executions ,1)
greatest函数返回参数列表中最大的一个,所以,达到了如果executions为0,就返回1的效果,是不是清爽优雅了许多?
还有一个用法,就是需要把时间由原始微秒转换成秒或者毫秒的时候,目前多数的写法是
转成秒:
elapsed_time / 100000
或者
转成毫秒:
elapsed_time / 1000
转成毫秒还好,后面3个0,转成秒时,后面6个0,有没有特别担心写少一位或者多写一位?
其实我上面的举例就少了一位,是错误的 ???? ,但是有多少人能够及时看出来?
这时候可以优雅地利用科学计数法写为另一种写法
转成秒:
elapsed_time / 1e6
这就很准确且易识别的转换成秒了。
Oracle的科学计数法很简单,前面是一个数字,中间跟一个e(大小写不限),后面跟一个整数(正负不限)就可以
n.nEm = n.n * 10^m
如:
1.1e1 = 1.1*10^1=11
10e6= 10 * 10^6 = 10^7 = 10,000,000
2e-2= 2 * 10^(-2)=0.02
而1e3,1e6,1e9 就正好是K/M/G或者毫/微/纳的进制转换
另外,在处理逻辑读/物理读的时候,如果希望把相关指标变成G或者M,也可以使用类似的写法。
以绝对大多数的8k块数据库而言:
标准写法是:
disk_reads*8192/1024/1024 -->转换为M
buffer_gets*8192/1024/1024/1024 -->转换成G
因为8192/1024/1024等于128,而128*1024约等于13万,上面的计算完全可以改写为
disk_reads/128
buffer_gets/13e4
当然,如果不是8k块大小,就不对了,需要相应调整
3个结合,就是:
select sql_id,elapsed_time/1e6 "执行时间(s)",elapsed_time/1e3/greatest(executions,1) as "单次执行(ms)",
disk_reads/128 as "物理读(M)",buffer_gets/13e4 "逻辑读(G)"
from v$sql
还有,如果分析的dba_hist_sqlstat, 不可避免的需要按时间段去做过滤,通常的做法是
select sql_id,to_char(begin_interval_time,'yyyymmdd') btime,round(elapsed_time_delta/1e6) "执行时间(s)",
round(elapsed_time_delta/1e3/greatest(executions_delta,1)) as "单次执行(ms)",
round(disk_reads_delta/128) as "物理读(M)",round(buffer_gets_delta/13e4) "逻辑读(G)"
from dba_hist_sqlstat sq,dba_hist_snapshot sn
where sn.snap_id = sq.snap_id and sn.instance_number = sq.instance_number and sn.dbid = sq.dbid
and begin_interval_time > sysdate - 3 -->限定3天内
order by 2 desc
其实,也可以利用Oracle支持自然连接(natural join)语法的特性,改写为:
select sql_id,to_char(begin_interval_time,'yyyymmdd') btime,round(elapsed_time_delta/1e6) "执行时间(s)",
round(elapsed_time_delta/1e3/greatest(executions_delta,1)) as "单次执行(ms)",
round(disk_reads_delta/128) as "物理读(M)",round(buffer_gets_delta/13e4) "逻辑读(G)"
from dba_hist_sqlstat sq natural join dba_hist_snapshot sn
where begin_interval_time > sysdate - 3 -->限定3天内
order by 2 desc
返回行数太多,不可避免需要分页,通常的写法是:
select * from (
select sql_id,to_char(begin_interval_time,'yyyymmdd') btime,round(elapsed_time_delta/1e6) "执行时间(s)",
round(elapsed_time_delta/1e3/greatest(executions_delta,1)) as "单次执行(ms)",
round(disk_reads_delta/128) as "物理读(M)",round(buffer_gets_delta/13e4) "逻辑读(G)"
from dba_hist_sqlstat sq natural join dba_hist_snapshot sn
where begin_interval_time > sysdate - 3 -->限定3天内
order by 2 desc
) where rownum <=20
如果你是12c以上的系统,还可以利用上fetch first N rows only的分页方法:
round(elapsed_time_delta/1e3/greatest(executions_delta,1)) as "单次执行(ms)",
round(disk_reads_delta/128) as "物理读(M)",round(buffer_gets_delta/13e4) "逻辑读(G)"
from dba_hist_sqlstat sq natural join dba_hist_snapshot sn
where begin_interval_time > sysdate - 3 -->限定3天内
order by 2 desc
fetch first 20 rows only
墨天轮原文链接:https://www.modb.pro/db/29713(复制到浏览器中打开或者点击“阅读原文”)
推荐阅读:144页!分享珍藏已久的数据库技术年刊
视频号,新的分享时代,关注我们,看看有什么新发现?
数据和云
ID:OraNews
如有收获,请划至底部,点击“在看”,谢谢!
点击下图查看更多 ↓
云和恩墨大讲堂 | 一个分享交流的地方
长按,识别二维码,加入万人交流社群
请备注:云和恩墨大讲堂
点个“在看”
你的喜欢会被看到❤
大罗讲SQL:如何优雅的进行SQL编写?相关推荐
- 使用Azure Data Factory优雅的迁移SQL Server 2000 DTS包
简介 最近搞了一个好玩的项目,客户的数据库从SQL Server 2000迁移到 Azure SQL .数据库数据迁移并不是难事,关键客户环境好玩的是使用了50多个DTS包,DTS包是比较古老的产品. ...
- 视频教程-19全新mysql教程零基础入门实战精讲mysql视频DBA数据库视频教程SQL教程-MySQL
19全新mysql教程零基础入门实战精讲mysql视频DBA数据库视频教程SQL教程 7年的开发架构经验,曾就职于国内一线互联网公司,开发工程师,现在是某创业公司技术负责人, 擅长语言有node/ja ...
- mybitys 动态sql 注释_mybatis注解动态sql详解
关于mybatis已经给大家讲过很多次了,下面要接着给大家介绍mybatis注解动态sql的内容,一起来了解一下mybatis注解开发之三种动态sql吧. 1.脚本sql 对于XML配置方式的动态SQ ...
- 引用:初探Sql Server 执行计划及Sql查询优化
引用:初探Sql Server 执行计划及Sql查询优化 原文:引用:初探Sql Server 执行计划及Sql查询优化 初探Sql Server 执行计划及Sql查询优化 收藏 MSSQL优化之-- ...
- dosbox 伪指令dd为什么会报错_什么是SQL函数?为什么使用SQL函数可能会带来问题?...
本文已收录GitHub,更有互联网大厂面试真题,面试攻略,高效学习资料等 函数在计算机语言的使用中贯穿始终,在 SQL 中我们也可以使用函数对检索出来的数据进行函数操作,比如求某列数据的平均值,或者求 ...
- 一起来玩AZURE SQL(二)AZURE SQL 初级使用篇
1.连接数据库 在ARM Portal上找到创建的数据库如图,我创建了一个数据库maxTestdb 点击maxTestdb 看到属性中服务器的名称是: maxtestdbserver.database ...
- 一起来玩AZURE SQL(一)AZURE SQL 介绍
1.什么是Azure SQL 在Azure上有PaaS层的SQL 服务,叫做AzureSQL数据库, AzureSQL是什么呢,简单讲就是,你需要使用数据库直接去申请,不关心后端怎么工作,不需要 ...
- SQL Server2016 新功能之SQL安装篇
SQL Server 的新功能让人眼花缭乱了,今天我们开始从SQL Server的安装说起,SQL安装说起来简单的过程,可以看看SQL 2016 有啥新的内容. 安装 SQL Server 2016的 ...
- vba mysql·教程_Excel VBA ADO SQL入门教程004:SQL中的Excel表
1. 上期我们聊了SQL常用查询语句中的字段查询,其简化版语法如下: SELECT 字段名 FROM 表名 当时我们说,FROM关键词指明了要获取字段信息的表的名称.倘若数据源是Excel表格,则需要 ...
- 掌握SQL Monitoring这些特性,SQL优化通通不在话下
目录 术语说明 概述 什么SQL会被SQL MONITORING监控到 找到Real Time SQL Monitoring入口 详解Real Time SQL Monitoring 1术语说明 在正 ...
最新文章
- linux下比较文件并输出,Linux使用diff命令比较文件找出文件之间相同的部分
- Access和sql server的语法区别
- python进程暂停_如何在Python中暂停多进程?
- dlibdotnet 人脸相似度源代码_使用dlib中的深度残差网络(ResNet)实现实时人脸识别 - supersayajin - 博客园...
- clipboard.js在弹出框中无法复制的问题
- P2016 战略游戏[树形dp]
- Markdown流程图实用工具汇总Obsidian+excalidraw
- 设计模式之装饰器模式
- 程序人生 - Nature封面:脑机接口突破,可将脑中“笔迹”转为屏幕字句,速度创纪录,准确率超高
- 数据仓库系列(四)数仓架构以及多维数据模型的设计
- 低分怎么上计算机专科学校,低分“首选”这四个专业,不仅给全家能争光,专科也能进国企...
- SAP权限管理,我的理解
- 图床程序 php,开源免费PHP图床程序–Qchan
- 计算机视觉学习——投影与三维视觉——本征矩阵和基础矩阵
- 目标检测中的数据增强,包括bbox的变换
- 磁盘损坏无法修复怎么办
- java 打印水仙花数(通俗易懂)
- 1.树莓派、Python、STM32、上位机、局域网、PC智能遥控小车(含源码)
- 老牌网站skinsdog 狗网官网可直接取回CSGO饰品开箱网站
- 如何将PDF转换为Excel?免费PDF转Excel方法分享
热门文章
- scratch绘制多边形_如何使用Scratch 3绘制矢量图形
- linux 容器_Linux容器的幕后花絮
- ldap radius_在LDAP上使用RADIUS的好处
- 修复 IE 的文本3像素偏移Bug
- es6 Proxy.revocable()方法
- ROS笔记(13) 记录与回放数据
- 深度学习笔记(16) 误差分析(一)
- mysql 自动执行语句_MYSQL 定时自动执行任务
- android 内存检测框架,Android项目内存泄漏检测
- 简述python常用的函数模块_Python中常用的Python time模块常用函数