在  https://www.cnblogs.com/xiandedanteng/p/12677688.html 中我列举了三种求中值方案,其中日本人MICK的做法因为不适用于二百万结果集而放弃,取而代之是新方案一。

新方案一:

经过思考后我又得出了一种中值的新解法,那就是利用排序后正向序列和反向序列交叉点为中值区的原理,如果两个序列相减小于等于一则求所在区域的均值即可。

SQL:

select avg(a.salary) from
(select salary,dense_rank() over (order by salary asc) as seq,dense_rank() over (order by salary desc) as revseq from tb_employee order by salary) a where abs(a.seq-a.revseq)<=1

解释计划:

SQL> select avg(a.salary) from
2 (select salary,dense_rank() over (order by salary asc) as seq,dense_rank() over (order by salary desc) as revseq from tb_employee order by salary) a where abs(a.seq-a.revseq)<=1;
已用时间: 00: 00: 00.00 执行计划
----------------------------------------------------------
Plan hash value: 9035349 ---------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
---------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 39 | | 8850 (2)| 00:01:47 |
| 1 | SORT AGGREGATE | | 1 | 39 | | | |
|* 2 | VIEW | | 2000K| 74M| | 8850 (2)| 00:01:47 |
| 3 | WINDOW SORT | | 2000K| 7812K| 22M| 8850 (2)| 00:01:47 |
| 4 | WINDOW SORT | | 2000K| 7812K| 22M| 8850 (2)| 00:01:47 |
| 5 | TABLE ACCESS FULL| TB_EMPLOYEE | 2000K| 7812K| | 3045 (2)| 00:00:37 |
--------------------------------------------------------------------------------------------- Predicate Information (identified by operation id):
--------------------------------------------------- 2 - filter(ABS("A"."SEQ"-"A"."REVSEQ")<=1)

从Cost看是目前最快的。

执行时间:

SQL> select avg(a.salary) from
2 (select salary,dense_rank() over (order by salary asc) as seq,dense_rank() over (order by salary desc) as revseq from tb_employee order by salary) a where abs(a.seq-a.revseq)<=1; AVG(A.SALARY)
-------------
5500 已用时间: 00: 00: 02.46

从运行时间上看排第二。

经局部优化后两种方案SQL如下:

原有方案二:

select avg(b.salary) from
(select a.salary,abs(a.seq-a.revseq) as diff from (select id,salary,dense_rank() over (order by salary asc) as seq,dense_rank() over (order by salary desc) as revseq from tb_employee order by salary) a ) b
where b.diff=(select min(c.diff) from
(select abs(a.seq-a.revseq) as diff from (select dense_rank() over (order by salary asc) as seq,dense_rank() over (order by salary desc) as revseq from tb_employee order by salary) a ) c)

解释计划:

SQL> select avg(b.salary) from
2 (select a.salary,abs(a.seq-a.revseq) as diff from (select id,salary,dense_rank() over (order by salary asc) as seq,dense_rank() over (order by salary desc) as revseq from tb_employee order by salary) a ) b
3 where b.diff=(select min(c.diff) from
4 (select abs(a.seq-a.revseq) as diff from (select dense_rank() over (order by salary asc) as seq,dense_rank() over (order by salary desc) as revseq from tb_employee order by salary) a ) c);
已用时间: 00: 00: 00.00 执行计划
----------------------------------------------------------
Plan hash value: 3874635296 -----------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
-----------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 39 | | 19969 (2)| 00:04:00 |
| 1 | SORT AGGREGATE | | 1 | 39 | | | |
|* 2 | VIEW | | 2000K| 74M| | 11119 (2)| 00:02:14 |
| 3 | WINDOW SORT | | 2000K| 19M| 38M| 11119 (2)| 00:02:14 |
| 4 | WINDOW SORT | | 2000K| 19M| 38M| 11119 (2)| 00:02:14 |
| 5 | TABLE ACCESS FULL | TB_EMPLOYEE | 2000K| 19M| | 3045 (2)| 00:00:37 |
| 6 | SORT AGGREGATE | | 1 | 26 | | | |
| 7 | VIEW | | 2000K| 49M| | 8850 (2)| 00:01:47 |
| 8 | WINDOW SORT | | 2000K| 7812K| 22M| 8850 (2)| 00:01:47 |
| 9 | WINDOW SORT | | 2000K| 7812K| 22M| 8850 (2)| 00:01:47 |
| 10 | TABLE ACCESS FULL| TB_EMPLOYEE | 2000K| 7812K| | 3045 (2)| 00:00:37 |
----------------------------------------------------------------------------------------------- Predicate Information (identified by operation id):
--------------------------------------------------- 2 - filter(ABS("A"."SEQ"-"A"."REVSEQ")= (SELECT MIN(ABS("A"."SEQ"-"A"."REVSEQ"))
FROM (SELECT DENSE_RANK() OVER ( ORDER BY "SALARY") "SEQ",DENSE_RANK() OVER ( ORDER
BY INTERNAL_FUNCTION("SALARY") DESC ) "REVSEQ" FROM "TB_EMPLOYEE" "TB_EMPLOYEE" ORDER
BY "SALARY") "A"))

执行时间:

SQL> select avg(b.salary) from
2 (select a.salary,abs(a.seq-a.revseq) as diff from (select id,salary,dense_rank() over (order by salary asc) as seq,dense_rank() over (order by salary desc) as revseq from tb_employee order by salary) a ) b
3 where b.diff=(select min(c.diff) from
4 (select abs(a.seq-a.revseq) as diff from (select dense_rank() over (order by salary asc) as seq,dense_rank() over (order by salary desc) as revseq from tb_employee order by salary) a ) c);

AVG(B.SALARY)
-------------
5500

已用时间: 00: 00: 04.56

原有方案三:

select avg(a.salary) from
(select
salary,row_number() over (order by salary asc) as seq,row_number() over (order by salary desc) as revseq,(select ceil(count(*)/2) from tb_employee) as ceil
from tb_employee) a
where a.seq=a.ceil or a.revseq=a.ceil

解释计划:

SQL> select avg(a.salary) from
2 (select
3 salary,row_number() over (order by salary asc) as seq,row_number() over (order by salary desc) as revseq,(select ceil(count(*)/2) from tb_employee) as ceil
4 from tb_employee) a
5 where a.seq=a.ceil or a.revseq=a.ceil;
已用时间: 00: 00: 00.00 执行计划
----------------------------------------------------------
Plan hash value: 3541675306 -----------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
-----------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 52 | | 14656 (3)| 00:02:56 |
| 1 | SORT AGGREGATE | | 1 | 52 | | | |
| 2 | SORT AGGREGATE | | 1 | | | | |
| 3 | INDEX FAST FULL SCAN| SYS_C0012264 | 2000K| | | 1474 (2)| 00:00:18 |
|* 4 | VIEW | | 2000K| 99M| | 14656 (3)| 00:02:56 |
| 5 | WINDOW SORT | | 2000K| 7812K| 22M| 14656 (3)| 00:02:56 |
| 6 | WINDOW SORT | | 2000K| 7812K| 22M| 14656 (3)| 00:02:56 |
| 7 | TABLE ACCESS FULL | TB_EMPLOYEE | 2000K| 7812K| | 3045 (2)| 00:00:37 |
----------------------------------------------------------------------------------------------- Predicate Information (identified by operation id):
--------------------------------------------------- 4 - filter("A"."SEQ"="A"."CEIL" OR "A"."REVSEQ"="A"."CEIL")

消耗时间:

SQL> ;
1 select avg(b.salary) from
2 (select
3 salary,row_number() over (order by salary asc) as seq,row_number() over (order by salary desc) as revseq,(select ceil(count(*)/2) from tb_employee) as ceil
4 - filter("A"."SEQ"="A"."CEIL" OR "A"."REVSEQ"="A"."CEIL");
5* where a.seq=a.ceil or a.revseq=a.ceil
SQL> select avg(a.salary) from
2 (select
3 salary,row_number() over (order by salary asc) as seq,row_number() over (order by salary desc) as revseq,(select ceil(count(*)/2) from tb_employee) as ceil
4 from tb_employee) a
5 where a.seq=a.ceil or a.revseq=a.ceil; AVG(A.SALARY)
-------------
5498 已用时间: 00: 00: 01.98

而单查表数量的解释计划大家也参考看一下:

SQL> select count(*) from tb_employee;
已用时间: 00: 00: 00.01 执行计划
----------------------------------------------------------
Plan hash value: 2866911338 ------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Cost (%CPU)| Time |
------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 1474 (2)| 00:00:18 |
| 1 | SORT AGGREGATE | | 1 | | |
| 2 | INDEX FAST FULL SCAN| SYS_C0012264 | 2000K| 1474 (2)| 00:00:18 |
------------------------------------------------------------------------------

最后的大比拼表格:

方案 Cost 耗时
新方案一 8850 2.46秒
原有方案二 19946 4.56秒
原有方案三 14646 1.98

截至目前,方案三以较高效率胜出,新方案一其实也不错,原有方案三排第三位。

--2020年4月12日--

新三种求数列中值SQL之效率再比拼的更多相关文章

  1. Python max()方法扩展:求字典中值最大的键

    重要的应该写在前面[捂脸]   场景一:仅求最大值对应的键,代码如下: >>> dic = {'A':4, 'B':2, 'C':3} >>> max_key = ...

  2. C#中??和?分别是什么意思? 在ASP.NET开发中一些单词的标准缩写 C#SESSION丢失问题的解决办法 在C#中INTERFACE与ABSTRACT CLASS的区别 SQL命令语句小技巧 JQUERY判断CHECKBOX是否选中三种方法 JS中!=、==、!==、===的用法和区别 在对象比较中,对象相等和对象一致分别指的是什么?

    C#中??和?分别是什么意思? 在C#中??和?分别是什么意思? 1. 可空类型修饰符(?):引用类型可以使用空引用表示一个不存在的值,而值类型通常不能表示为空.例如:string str=null; ...

  3. 【算法随记三】小半径中值模糊的急速实现(16MB图7.5ms实现) + Photoshop中蒙尘和划痕算法解读。

    在本人的博客里,分享了有关中值模糊的O(1)算法,详见:任意半径中值滤波(扩展至百分比滤波器)O(1)时间复杂度算法的原理.实现及效果 ,这里的算法的执行时间和参数是无关的.整体来说,虽然速度也很快, ...

  4. java数组中的三种排序方法中的冒泡排序方法

    我记得我大学学java的时候,怎么就是搞不明白这三种排序方法,也一直不会,现在我有发过来学习下这三种方法并记录下来. 首先说说冒泡排序方法:冒泡排序方法就是把数组中的每一个元素进行比较,如果第i个元素 ...

  5. Python 列表(List) 的三种遍历(序号和值)方法

    三种遍历列表里面序号和值的方法: 最近学习python这门语言,感觉到其对自己的工作效率有很大的提升,特在情人节这一天写下了这篇博客,下面废话不多说,直接贴代码 #!/usr/bin/env pyth ...

  6. [ 原创 ]学习笔记-三种向ListView中填充简单文本的方法

    Android 中ListView是很重要的一块内容 掌握ListView的基本用法 对学习安卓起着举足轻重的作用 今天就介绍一下三种向ListView 填充简单文本的方法 填充其他数据类型的用法之后 ...

  7. 求数列中第K大的数

    原创 利用到快速排序的思想,快速排序思想:https://www.cnblogs.com/chiweiming/p/9188984.html array代表存放数列的数组,K代表第K大的数,mid代表 ...

  8. C#三种判断数据库中取出的字段值是否为空(NULL) 的方法

    操作数据库,需要判断返回的字段值是否为空,收集了3种方法供参考 1 通过System.DBNull判断,网上大部分都使用这个方法. DataTable dt;                     ...

  9. Spring之jdbcTemplate:查询的三种方式(单个值、单个对象、对象集合)

    JdbcTemplateDemo2.java package helloworld.jdbcTemplate; import org.springframework.jdbc.core.JdbcTem ...

随机推荐

  1. 2020-08-08:有一批气象观测站,现需要获取这些站点的观测数据,并存储到 Hive 中。但是气象局只提供了 api 查询,每次只能查询单个观测点。那么如果能够方便快速地获取到所有的观测点的数据?

    福哥答案2020-08-08: 参考答案:A.通过shell 或python 等调用api,结果先暂存本地,最后将本地文件上传到 Hive 中.B.通过 datax 的 httpReader 和 hd ...

  2. 2020-05-11:redis 10G 内存开一个实例 和redis 1G内存开10个实例有什么区别

    福哥答案2020-05-11: 此答案不完善,仅供参考.开10个实例相对更占资源,在多核下能充分利用资源.

  3. three.js 制作机房(上)

    three.js使用的人太少了,一个博文就几百个人看,之前发js基础哪怕是d3都会有几千的阅读量,看看以后考虑说一说d3了,哈哈.吐槽完毕回归正题.前几天郭先生看到网上有人开发了3D机房,正愁博客没什 ...

  4. [luogu4140] 奇数国

    题目 在一片美丽的大陆上有100000个国家,记为1到100000.这里经济发达,有数不尽的账房,并且每个国家有一个银行.某大公司的领袖在这100000个银行开户时都存了3大洋,他惜财如命,因此会不时 ...

  5. Manacher(马拉车)算法(jekyll迁移)

    layout: post title: Manacher(马拉车)算法 date: 2019-09-07 author: xiepl1997 cover: 'assets/img/manacher.p ...

  6. vue cli3.0使用svg全过程

    VUE-cli3使用 svg-sprite-loader svg-sprite-loader 的插件,用来根据导入的 svg 文件自动生成 symbol 标签并插入 html 1.安装依赖 npm i ...

  7. eclipse中点击pre-commit Request to ReviewBoard,预提交框不显示问题

    需要设置:

  8. python基础 Day11

    python Day11 函数中默认参数的陷阱 只针对默认参数是可变的数据类型(如果你的默认参数指向的是可变的数据类型,那么你无论调用多少次默认参数,都是同一个) def test(name,list ...

  9. python open函数初习

    open("路径","打开方式")  打开方式:'r'只读模式,‘w’写模式,‘a’追加模式 ‘b’二进制模式,‘+’读/写模式.例: fh=open(&quo ...

  10. Dubbo详解

    什么是DubboDubbo是一个分布式服务框架,致力于提供高性能和透明化的远程服务调用方案,这容易和负载均衡弄混,负载均衡是对外提供一个公共地址,请求过来时通过轮询.随机等,路由到不同server.目 ...