墨墨导读: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编写?相关推荐

  1. 使用Azure Data Factory优雅的迁移SQL Server 2000 DTS包

    简介 最近搞了一个好玩的项目,客户的数据库从SQL Server 2000迁移到 Azure SQL .数据库数据迁移并不是难事,关键客户环境好玩的是使用了50多个DTS包,DTS包是比较古老的产品. ...

  2. 视频教程-19全新mysql教程零基础入门实战精讲mysql视频DBA数据库视频教程SQL教程-MySQL

    19全新mysql教程零基础入门实战精讲mysql视频DBA数据库视频教程SQL教程 7年的开发架构经验,曾就职于国内一线互联网公司,开发工程师,现在是某创业公司技术负责人, 擅长语言有node/ja ...

  3. mybitys 动态sql 注释_mybatis注解动态sql详解

    关于mybatis已经给大家讲过很多次了,下面要接着给大家介绍mybatis注解动态sql的内容,一起来了解一下mybatis注解开发之三种动态sql吧. 1.脚本sql 对于XML配置方式的动态SQ ...

  4. 引用:初探Sql Server 执行计划及Sql查询优化

    引用:初探Sql Server 执行计划及Sql查询优化 原文:引用:初探Sql Server 执行计划及Sql查询优化 初探Sql Server 执行计划及Sql查询优化 收藏 MSSQL优化之-- ...

  5. dosbox 伪指令dd为什么会报错_什么是SQL函数?为什么使用SQL函数可能会带来问题?...

    本文已收录GitHub,更有互联网大厂面试真题,面试攻略,高效学习资料等 函数在计算机语言的使用中贯穿始终,在 SQL 中我们也可以使用函数对检索出来的数据进行函数操作,比如求某列数据的平均值,或者求 ...

  6. 一起来玩AZURE SQL(二)AZURE SQL 初级使用篇

    1.连接数据库 在ARM Portal上找到创建的数据库如图,我创建了一个数据库maxTestdb 点击maxTestdb 看到属性中服务器的名称是: maxtestdbserver.database ...

  7. 一起来玩AZURE SQL(一)AZURE SQL 介绍

     1.什么是Azure SQL 在Azure上有PaaS层的SQL 服务,叫做AzureSQL数据库, AzureSQL是什么呢,简单讲就是,你需要使用数据库直接去申请,不关心后端怎么工作,不需要 ...

  8. SQL Server2016 新功能之SQL安装篇

    SQL Server 的新功能让人眼花缭乱了,今天我们开始从SQL Server的安装说起,SQL安装说起来简单的过程,可以看看SQL 2016 有啥新的内容. 安装 SQL Server 2016的 ...

  9. vba mysql·教程_Excel VBA ADO SQL入门教程004:SQL中的Excel表

    1. 上期我们聊了SQL常用查询语句中的字段查询,其简化版语法如下: SELECT 字段名 FROM 表名 当时我们说,FROM关键词指明了要获取字段信息的表的名称.倘若数据源是Excel表格,则需要 ...

  10. 掌握SQL Monitoring这些特性,SQL优化通通不在话下

    目录 术语说明 概述 什么SQL会被SQL MONITORING监控到 找到Real Time SQL Monitoring入口 详解Real Time SQL Monitoring 1术语说明 在正 ...

最新文章

  1. linux下比较文件并输出,Linux使用diff命令比较文件找出文件之间相同的部分
  2. Access和sql server的语法区别
  3. python进程暂停_如何在Python中暂停多进程?
  4. dlibdotnet 人脸相似度源代码_使用dlib中的深度残差网络(ResNet)实现实时人脸识别 - supersayajin - 博客园...
  5. clipboard.js在弹出框中无法复制的问题
  6. P2016 战略游戏[树形dp]
  7. Markdown流程图实用工具汇总Obsidian+excalidraw
  8. 设计模式之装饰器模式
  9. 程序人生 - Nature封面:脑机接口突破,可将脑中“笔迹”转为屏幕字句,速度创纪录,准确率超高
  10. 数据仓库系列(四)数仓架构以及多维数据模型的设计
  11. 低分怎么上计算机专科学校,低分“首选”这四个专业,不仅给全家能争光,专科也能进国企...
  12. SAP权限管理,我的理解
  13. 图床程序 php,开源免费PHP图床程序–Qchan
  14. 计算机视觉学习——投影与三维视觉——本征矩阵和基础矩阵
  15. 目标检测中的数据增强,包括bbox的变换
  16. 磁盘损坏无法修复怎么办
  17. java 打印水仙花数(通俗易懂)
  18. 1.树莓派、Python、STM32、上位机、局域网、PC智能遥控小车(含源码)
  19. 老牌网站skinsdog 狗网官网可直接取回CSGO饰品开箱网站
  20. 如何将PDF转换为Excel?免费PDF转Excel方法分享

热门文章

  1. scratch绘制多边形_如何使用Scratch 3绘制矢量图形
  2. linux 容器_Linux容器的幕后花絮
  3. ldap radius_在LDAP上使用RADIUS的好处
  4. 修复 IE 的文本3像素偏移Bug
  5. es6 Proxy.revocable()方法
  6. ROS笔记(13) 记录与回放数据
  7. 深度学习笔记(16) 误差分析(一)
  8. mysql 自动执行语句_MYSQL 定时自动执行任务
  9. android 内存检测框架,Android项目内存泄漏检测
  10. 简述python常用的函数模块_Python中常用的Python time模块常用函数