需求:取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. 算法学习笔记:2-SAT

    SAT 是适定性(Satisfiability)问题的简称.一般形式为 k - 适定性问题,简称 k-SAT.而当 \(k>2\) 时该问题为 NP 完全的.所以我们只研究 \(k=2\) 的情 ...

  2. web新手第二周知识汇总

    这周学习了盒模型以及一些定位的知识,现在简单做下汇总 盒模型组成部分: ie浏览器默认值是border-box content(内容盒)蓝色 padding(内容和边框的距离 绿色 填充盒包含内容)b ...

  3. 【Docker】 Error running deviceCreate (CreateSnapDeviceRaw)

    问题详细信息: [root@passport docker]# docker-compose -f docker-compose.yml up -ddocker_db_1_1651de706222 i ...

  4. 2020-05-26:TCP四次挥手过程?

    福哥答案2020-05-26:

  5. Python对list操作的一些小技巧

    Python对list操作的一些小技巧  由于要搞数学建模,于是从熟悉已久的C++转战Python.虽然才上手,但是Python的语法糖就让我大呼过瘾.不得不说相比于C/C++,Python对于数据的 ...

  6. JavaScript基础-05-数组、Date对象、Math、包装类、字符串方法

    数组(Array) 1. 数组 数组也是一个对象,不同点:普通对象是使用字符串作为属性名的,数组是使用数字作为索引操作元素. 数组的存储性能比普通对象要好,在开发中经常使用数组来存储一些数据. 向数组 ...

  7. apache+djnago+websocket 部署配置

    部署Apache服务器 1.apache服务的安装这里不做赘述,因为网上一大堆. 链接:https://blog.csdn.net/qq_24394093/article/details/905501 ...

  8. Webfunny知识分享:JS错误监控

    现在的前端开发已不再是刀耕火种的年代了,各种框架.编译工具层出不穷,前端监控系统也不甘其后,遍地开花. 前端正承受着越来越重的职责,前端的业务也变得越来越复杂,此时此刻我们就更需要一套完善的监控系统来 ...

  9. .Net Core中的诊断日志DiagnosticSource讲解

    前言     近期由于需要进行分布式链路跟踪系统的技术选型,所以一直在研究链路跟踪相关的框架.作为能在.Net Core中使用的APM,SkyWalking自然成为了首选.SkyAPM-dotnet是 ...

  10. 第3篇scrum冲刺(5.23)

    一.站立会议 1.照片 2.工作安排 成员 昨天已完成的工作 今天的工作安排 困难 陈芝敏  调用小程序接口获取用户微信登录权限,初始化  完成云开发配置,初始化数据库: 进度较慢,后面可能会有点困难 ...