关于取表中id最大值+1的select语句,哪种效率更高?
需求:取stock表中id最大值+1,作为下一个id值。
特殊情况:考虑到表中会没有值,max(id)会返回空,因此需要用case when进行判断。
实现一:select (case max(id) is null when true then 0 else max(id)+1 end) from stock
实现二:select (case (select count(*) from stock) when 0 then 0 else max(id)+1 end) from stock
效率分析:
实现一相对于实现二不取数量,在索引的帮助下也能快速取值,因此效率应该比实现二高。
分析之验证:
(MySQL数据库)
stock表中没有数据时:
mysql> explain select (case max(id) is null when true then 0 else max(id)+1 end) from stock;
+----+-------------+-------+------+---------------+------+---------+------+------+-------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------------------+
| 1 | SIMPLE | NULL | NULL | NULL | NULL | NULL | NULL | NULL | No matching min/max row |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------------------+
1 row in set (0.00 sec) mysql> explain select (case (select count(*) from stock) when 0 then 0 else max(id)+1 end) from stock;
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------------------+
| 1 | PRIMARY | NULL | NULL | NULL | NULL | NULL | NULL | NULL | No matching min/max row |
| 2 | SUBQUERY | stock | index | NULL | PRIMARY | 4 | NULL | 3749 | Using index |
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------------------+
2 rows in set (0.05 sec)
stock表中有数据时:
mysql> select count(*) from stock;
+----------+
| count(*) |
+----------+
| 3768 |
+----------+
1 row in set (0.00 sec) mysql> explain select (case max(id) is null when true then 0 else max(id)+1 end) from stock;
+----+-------------+-------+------+---------------+------+---------+------+------+------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+------+------------------------------+
| 1 | SIMPLE | NULL | NULL | NULL | NULL | NULL | NULL | NULL | Select tables optimized away |
+----+-------------+-------+------+---------------+------+---------+------+------+------------------------------+
1 row in set (0.00 sec) mysql> desc select (case (select count(*) from stock) when 0 then 0 else max(id)+1 end) from stock;
+----+-------------+-------+-------+---------------+---------+---------+------+------+------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+---------+---------+------+------+------------------------------+
| 1 | PRIMARY | NULL | NULL | NULL | NULL | NULL | NULL | NULL | Select tables optimized away |
| 2 | SUBQUERY | stock | index | NULL | PRIMARY | 4 | NULL | 3696 | Using index |
+----+-------------+-------+-------+---------------+---------+---------+------+------+------------------------------+
2 rows in set (0.00 sec)
分析之验证:
oracle数据库
MySQL版的SQL不能直接在oracle里使用,因此需要改写成:
方案一:select nvl(max(id)+1,0) from stock;
方案二:select (case count(*) when 0 then 0 else max(id)+1 end) from stock
然后我模拟做了3744条记录,跑解释计划确实方案二慢.
方案一的执行计划:
SQL> select nvl(max(id)+1,0) from stock;
已用时间: 00: 00: 00.00 执行计划
----------------------------------------------------------
Plan hash value: 1547204082 --------------------------------------------------------------------------------
----------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)|
Time | --------------------------------------------------------------------------------
----------- | 0 | SELECT STATEMENT | | 1 | 13 | 2 (0)|
00:00:01 | | 1 | SORT AGGREGATE | | 1 | 13 | |
| | 2 | INDEX FULL SCAN (MIN/MAX)| SYS_C0011050 | 1 | 13 | 2 (0)|
00:00:01 | --------------------------------------------------------------------------------
----------- Note
-----
- dynamic sampling used for this statement (level=2)
方案二的执行计划:
SQL> select (case count(*) when 0 then 0 else max(id)+1 end) from stock;
已用时间: 00: 00: 00.00 执行计划
----------------------------------------------------------
Plan hash value: 916654 --------------------------------------------------------------------------------
------ | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time
| --------------------------------------------------------------------------------
------ | 0 | SELECT STATEMENT | | 1 | 13 | 5 (0)| 00:0
0:01 | | 1 | SORT AGGREGATE | | 1 | 13 | |
| | 2 | INDEX FAST FULL SCAN| SYS_C0011050 | 3744 | 48672 | 5 (0)| 00:0
0:01 | --------------------------------------------------------------------------------
------ Note
-----
- dynamic sampling used for this statement (level=2)
--2020年5月2日--
关于取表中id最大值+1的select语句,哪种效率更高?的更多相关文章
- 个人学习记录--取表中Name相同的最大值,非Group By,可延伸
), qy ), je INT); INSERT INTO @t SELECT '产品一', '北京', UNION ALL SELECT '产品一', '上海', UNION ALL SELECT ...
- 【HANA系列】SAP HANA SQL取表中每行最小值
公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[HANA系列]SAP HANA SQL取表中每 ...
- oracle通过sql随机取表中的10条记录
oracle通过sql随机取表中的10条记录: SELECT * FROM (SELECT * FROM T_USER ORDER BY DBMS_RANDOM.RANDOM()) WHERE Row ...
- B表中的pid对应A表中id,查询A表中数据,根据b表中对应a表中该id的数据数目排序
B表中的pid对应A表中id,查询A表中数据,根据b表中对应a表中该id的数据数目排序 select a.*,count(*) as c from a left join b on a.id=b.ai ...
- Oracle 实现表中id字段自增长
Oracle 实现表中id字段自增长 最近正在学习Oracle的时候发现Oracle表中的字段不能像mysql中那样可以用auto increment修饰字段从而让id这种主键字段实现自增长. 那Or ...
- 转发:maven打包时始终出现以下提示:-source 1.3 中不支持泛型(请使用 -source 5 或更高版本以启用泛型)
maven打包时始终出现以下提示: 1.-source 1.3 中不支持泛型(请使用 -source 5 或更高版本以启用泛型)List<User> userList= new Array ...
- Spring AOP中的JDK和CGLib动态代理哪个效率更高?
一.背景 今天有小伙伴面试的时候被问到:Spring AOP中JDK 和 CGLib动态代理哪个效率更高? 二.基本概念 首先,我们知道Spring AOP的底层实现有两种方式:一种是JDK动态代理, ...
- 在类中,调用这个类时,用$this->video_model是不是比每次调用这个类时D('Video')效率更高呢
在类中,调用这个类时,用$this->video_model是不是比每次调用这个类时D('Video')效率更高呢
- O(1)取Queue中的最大值
实现原理: 1.利用Stack的先进后出的特性,实现一个MaxStack,MaxStack中用一个Stack记录当前的值,一个Stack记录当前的最大值. 2.用2个MaxStack实现MaxQueu ...
随机推荐
- Paper English
论文中的英语 单词 a arange 整理 ambiguity 含糊的 aggregate 总量 auxiliary 辅助的 alleviate 缓解 aberrant 异常的 akin 类似的 Ac ...
- 使用Python语言通过PyQt5和socket实现UDP服务器
前言 最近做了一个小软件,记录一下相关内容. 已有条件 现在已有一个硬件设备作为客户端(暂称其为"电路"). 基于SIM卡,电路可以通过UDP协议传输数据(程序已经内置在电路中), ...
- Flutter 容器(6) - FractionallySizedBox
FractionallySizedBox 用法与SizedBox类似,只不过FractionallySizedBox的宽高是百分比大小,widthFactor,heightFactor参数就是相对于父 ...
- STL函数库的应用第四弹——全排列(+浅谈骗分策略)
因为基础算法快学完了,图论又太难(我太蒻了),想慢慢学. 所以暂时不写关于算法的博客了,但又因为更新博客的需要,会多写写关于STL的博客. (毕竟STL函数库还是很香的(手动滑稽)) 请出今天主角:S ...
- CSS动画实例:Loading加载动画效果(三)
3.小圆型Loading 这类Loading动画的基本思想是:在呈现容器中定义1个或多个子层,再对每个子层进行样式定义,使得其均显示为一个实心圆形,最后编写关键帧动画控制,使得各个实心圆或者大小发生改 ...
- Ubuntu18.04 安装 Fabric & 使用 Fabric 测试网络
前言: 本文介绍在 Ubuntu 18.04 中安装 Fabric, 并对 官方文档中的一个小案例(Using the Fabric test network)进行测试. 目的: 初步了解 Fabri ...
- OpenJDK和OracleJDK的区别
在2006年11月13日的JavaOne大会上,Sun公司(当时还没被收购)宣布计划要把Java开源,在随后的一年多时间内,它陆续地将JDK的各个部分在GPL v2(GNU General Publi ...
- linux下的scp传输文件
转载于:http://moyu2010.blog.163.com/blog/static/177439041201112710243064/,再次谢谢作者. 1.功能说明scp就是security c ...
- SpringBoot--- Shiro(拦截,认证)、Thymeleaf(模板引擎)
SpringBoot--- Shiro(拦截,认证).Thymeleaf(模板引擎) 环境 IDEA :2020.1 SpringBoot: 2.3.3 Java : 8 版本依赖: shiro- ...
- 极简 Node.js 入门 - 3.4 文件夹写入
极简 Node.js 入门系列教程:https://www.yuque.com/sunluyong/node 本文更佳阅读体验:https://www.yuque.com/sunluyong/node ...