关于验证表中有无数据的方法比较(r2笔记54天)
在平时的工作中,有时候需要准备一些脚本,比如能够简单验证一下表是否可访问,或者验证表中有无数据等。
今天在测试环境进行了简单的模拟,发现还是有很大的差别。
简单来说,要实现如上的需求有两种方式,一种是通过count来判断,另外一种是通过rowid来判断。
举个例子。
先来看一个大表,但是某个分区没有数据的情况。
select count(1) from APP_TMP.INVOICE partition(A8_B8) where rownum<=1;
Execution Plan
----------------------------------------------------------
Plan hash value: 1238501171
----------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Cost (%CPU)| Time | Pstart| Pstop |
----------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 1 (0)| 00:00:01 | | |
| 1 | SORT AGGREGATE | | 1 | | | | |
|* 2 | COUNT STOPKEY | | | | | | |
| 3 | PARTITION RANGE SINGLE| | 1 | 1 (0)| 00:00:01 | 39 | 39 |
| 4 | INDEX FULL SCAN | INVOICE_1IX | 1 | 1 (0)| 00:00:01 | 39 | 39 |
----------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter(ROWNUM<=1)
Statistics
----------------------------------------------------------
1736 recursive calls
0 db block gets
7308 consistent gets
0 physical reads
0 redo size
525 bytes sent via SQL*Net to client
520 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
18 sorts (memory)
0 sorts (disk)
1 rows processed
SQL> select rowid from APP_TMP.INVOICE partition(A8_B8) where rownum<=1
2 /
no rows selected
Execution Plan
----------------------------------------------------------
Plan hash value: 1950573833
-----------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop |
-----------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 12 | 1 (0)| 00:00:01 | | |
|* 1 | COUNT STOPKEY | | | | | | | |
| 2 | PARTITION RANGE SINGLE| | 1 | 12 | 1 (0)| 00:00:01 | 39 | 39 |
| 3 | INDEX FULL SCAN | INVOICE_1IX | 1 | 12 | 1 (0)| 00:00:01 | 39 | 39 |
-----------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter(ROWNUM<=1)
Statistics
----------------------------------------------------------
5 recursive calls
0 db block gets
4 consistent gets
0 physical reads
0 redo size
333 bytes sent via SQL*Net to client
509 bytes received via SQL*Net from client
1 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
0 rows processed
大体来说,查询时间都基本一致,可能使用Rowid的方式效率要略微好一些,这两种方式采用的执行计划也是不同的。注意如上标黄的部分。
再来测试一个大表中分区数据最多的。
SQL> alter session force parallel query parallel 16;
Session altered.
Elapsed: 00:00:00.00
SQL> select count(1) from AGREEMENT_PARAM partition(AMAXVALUE);
78085245
Elapsed: 00:00:04.89
数据有7千多万,算比较多的了。
然后再次尝试count,和rowid方式
SQL> select count(1) from AGREEMENT_PARAM partition(AMAXVALUE) where rownum<1;
Execution Plan
----------------------------------------------------------
Plan hash value: 2234036749
-----------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Cost (%CPU)| Time | Pstart| Pstop |
-----------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 41914 (1)| 00:08:23 | | |
| 1 | SORT AGGREGATE | | 1 | | | | |
|* 2 | COUNT STOPKEY | | | | | | |
| 3 | PARTITION RANGE SINGLE| | 78M| 41914 (1)| 00:08:23 | 11 | 11 |
| 4 | INDEX FULL SCAN | AGREEMENT_PARAM_PK | 78M| 41914 (1)| 00:08:23 | 11 | 11 |
-----------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter(ROWNUM<1)
Statistics
----------------------------------------------------------
162 recursive calls
0 db block gets
234 consistent gets
0 physical reads
0 redo size
525 bytes sent via SQL*Net to client
520 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
8 sorts (memory)
0 sorts (disk)
1 rows processed
SQL> select rowid from AGREEMENT_PARAM partition(AMAXVALUE) where rownum<2;
Elapsed: 00:00:00.01
Execution Plan
----------------------------------------------------------
Plan hash value: 4116254344
------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop |
------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 12 | 1 (0)| 00:00:01 | | |
|* 1 | COUNT STOPKEY | | | | | | | |
| 2 | PARTITION RANGE SINGLE| | 1 | 12 | 1 (0)| 00:00:01 | 11 | 11 |
| 3 | INDEX FULL SCAN | AGREEMENT_PARAM_PK | 1 | 12 | 1 (0)| 00:00:01 | 11 | 11 |
------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter(ROWNUM<2)
Statistics
----------------------------------------------------------
1 recursive calls
0 db block gets
4 consistent gets
0 physical reads
0 redo size
537 bytes sent via SQL*Net to client
520 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
可以看到,rowid的优势就出来了,查询速度要快的多。时间上提高了很多倍。逻辑读也少了很了很多。
所以大家在平时准备类似的脚本的时候,可以优先考虑rowid,毕竟这是oracle底层支持比较好的方案。
最后有的朋友,可能疑惑为什么不适用rowid=0这种方式呢。可能效果还要好些。
测试结果如下。我就不等待它执行完成了,执行了40秒还是没有反应。
1* select count(1) from AGREEMENT_PARAM partition(AMAXVALUE) where rownum=0
*
ERROR at line 1:
ORA-01013: user requested cancel of current operation
Elapsed: 00:00:39.94
- sql语句查询到整个数据库的容量
- 神奇的go语言
- 备库查询导致的ORA-01110错误及修复(r8笔记第67天)
- SQL客户端DBvisualize直接导入数据出现中文乱码
- Python基础整理操作积累
- 让AI给颜值打分?应该是最公正的裁判了!
- orion的简单测试 (r8笔记第75天)
- golang ftp客户端示例 支持断点续传
- python 网页特征提取XPATH(两天玩转) 第一天
- 和开发同学讨论的一个技术问题(r8笔记第73天)
- 剖析Oracle中oerr命令(r8笔记第70天)
- 甜品店切蛋糕问题(动态规划,Go语言实现)
- SQL—复制表结构及其数据
- python连接SQL报错:1366, "Incorrect string value: '\xF0\x9F\x98\x81'
- 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 数组属性和方法
- Linux中环境变量配置的步骤详解
- 详解Linux搭建DNS服务器
- 一篇文章弄懂Linux磁盘和磁盘分区
- Ubuntu 17.04系统下源码编译安装opencv的步骤详解
- 如何在Linux中自定义bash命令提示符
- 详解如何在Linux上一次性批量重命名一组文件
- 虚拟机中centos修改时间的方法
- Ubuntu 18.04 Server 设置静态IP 的方法
- 嵌入式Linux重启QT应用程序的简单办法(基于QT4.8 qws)
- CentOS下MySQL的彻底卸载的几种方法
- centos7中安装Android SDK的方法步骤
- centos配置ssh免密码登录后仍要输入密码的解决方法
- CentOS7.2安装Nginx的方法步骤
- CentOS安装Python2.7与Python2.6并存的方法
- 详解Centos下YUM安装PHP的两种方式