需求:取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语句,哪种效率更高?的更多相关文章

  1. 个人学习记录--取表中Name相同的最大值,非Group By,可延伸

    ), qy ), je INT); INSERT INTO @t SELECT '产品一', '北京', UNION ALL SELECT '产品一', '上海', UNION ALL SELECT ...

  2. 【HANA系列】SAP HANA SQL取表中每行最小值

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[HANA系列]SAP HANA SQL取表中每 ...

  3. oracle通过sql随机取表中的10条记录

    oracle通过sql随机取表中的10条记录: SELECT * FROM (SELECT * FROM T_USER ORDER BY DBMS_RANDOM.RANDOM()) WHERE Row ...

  4. 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 ...

  5. Oracle 实现表中id字段自增长

    Oracle 实现表中id字段自增长 最近正在学习Oracle的时候发现Oracle表中的字段不能像mysql中那样可以用auto increment修饰字段从而让id这种主键字段实现自增长. 那Or ...

  6. 转发:maven打包时始终出现以下提示:-source 1.3 中不支持泛型(请使用 -source 5 或更高版本以启用泛型)

    maven打包时始终出现以下提示: 1.-source 1.3 中不支持泛型(请使用 -source 5 或更高版本以启用泛型)List<User> userList= new Array ...

  7. Spring AOP中的JDK和CGLib动态代理哪个效率更高?

    一.背景 今天有小伙伴面试的时候被问到:Spring AOP中JDK 和 CGLib动态代理哪个效率更高? 二.基本概念 首先,我们知道Spring AOP的底层实现有两种方式:一种是JDK动态代理, ...

  8. 在类中,调用这个类时,用$this->video_model是不是比每次调用这个类时D('Video')效率更高呢

    在类中,调用这个类时,用$this->video_model是不是比每次调用这个类时D('Video')效率更高呢  

  9. O(1)取Queue中的最大值

    实现原理: 1.利用Stack的先进后出的特性,实现一个MaxStack,MaxStack中用一个Stack记录当前的值,一个Stack记录当前的最大值. 2.用2个MaxStack实现MaxQueu ...

随机推荐

  1. C# Thread.Name 的作用和意义

    Thread.Name属性 C#的线程提供Thread.Name属性.这意味着每个线程可以设定一个Name属性来标志它们. Name属性的使用时特性 线程的Name属性默认情况下是null.该值只能被 ...

  2. linux7手动添加systemctl启动程序

    1.路径 [root@angrymushrooms01 system]# pwd /usr/lib/systemd/system 2.脚本内容 vim xxx.service ------------ ...

  3. 2020-04-20:对Java接口代理模式的实现原理的理解?

    静态代理Java中的静态代理要求代理类(ProxySubject)和委托类(RealSubject)都实现同一个接口(Subject).静态代理中代理类在编译期就已经确定,而动态代理则是JVM运行时动 ...

  4. C#LeetCode刷题之#641-设计循环双端队列(Design Circular Deque)

    问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/4132 访问. 设计实现双端队列. 你的实现需要支持以下操作: M ...

  5. Spring Cloud Config Client 超时与重试

    简介 有时客户端需要在 config server 无响应时进行重试,以给 config server 时间进行恢复.利用 spring 提供的重试组件,我们可以方便的配置重试机制,包括重试间隔,重试 ...

  6. 获取网页js代码的一个方法

    这个是看了别人的代码,稍加修改而成的.怕时间长忘了,在这里记一笔: console.log(require(["foo:bar.js"]).prototype.someMethod ...

  7. 分享一个bootstrap的上一步,下一步的插件

    效果图: 下载链接: https://www.daimabiji.com/index.php?m=content&c=down&a_k=ae0fI1gZyLT7oao56Pgu-dye ...

  8. Jmeter 常用函数(19)- 详解 __BeanShell

    如果你想查看更多 Jmeter 常用函数可以在这篇文章找找哦 https://www.cnblogs.com/poloyy/p/13291704.htm 作用 执行 BeanShell 脚本,并返回结 ...

  9. 操作系统-I/O(2)设备的分配

    作业执行前对设备提出申请时,指定某台具体的物理设备会让设备分配变得简单,但如果所指定设备出现故障,即便计算机系统中有同类设备也不能运行 设备独立性:用户通常不指定物理设备,而是指定逻辑设备,使得用户作 ...

  10. 常用生成模型代码大全(pytorch/tensorflow)

    感谢大佬开源分享 代码详见:https://github.com/wiseodd/generative-models