赵延东的一亩三分地

赵延东的一亩三分地

系列文章目录

【SQL开发实战技巧】系列(一):关于SQL不得不说的那些事
【SQL开发实战技巧】系列(二):简单单表查询
【SQL开发实战技巧】系列(三):SQL排序的那些事
【SQL开发实战技巧】系列(四):从执行计划讨论UNION ALL与空字符串&UNION与OR的使用注意事项
【SQL开发实战技巧】系列(五):从执行计划看IN、EXISTS 和 INNER JOIN效率,我们要分场景不要死记网上结论
【SQL开发实战技巧】系列(六):从执行计划看NOT IN、NOT EXISTS 和 LEFT JOIN效率,记住内外关联条件不要乱放
【SQL开发实战技巧】系列(七):从有重复数据前提下如何比较出两个表中的差异数据及对应条数聊起
【SQL开发实战技巧】系列(八):聊聊如何插入数据时比约束更灵活的限制数据插入以及怎么一个insert语句同时插入多张表
【SQL开发实战技巧】系列(九):一个update误把其他列数据更新成空了?Merge改写update!给你五种删除重复数据的写法!
【SQL开发实战技巧】系列(十):从拆分字符串、替换字符串以及统计字符串出现次数说起
【SQL开发实战技巧】系列(十一):拿几个案例讲讲translate|regexp_replace|listagg|wmsys.wm_concat|substr|regexp_substr常用函数
【SQL开发实战技巧】系列(十二):三问(如何对字符串字母去重后按字母顺序排列字符串?如何识别哪些字符串中包含数字?如何将分隔数据转换为多值IN列表?)
【SQL开发实战技巧】系列(十三):讨论一下常用聚集函数&通过执行计划看sum()over()对员工工资进行累加
【SQL开发实战技巧】系列(十四):计算消费后的余额&计算银行流水累计和&计算各部门工资排名前三位的员工
【SQL开发实战技巧】系列(十五):查找最值所在行数据信息及快速计算总和百之max/min() keep() over()、fisrt_value、last_value、ratio_to_report
【SQL开发实战技巧】系列(十六):数据仓库中时间类型操作(初级)日、月、年、时、分、秒之差及时间间隔计算
【SQL开发实战技巧】系列(十七):数据仓库中时间类型操作(初级)确定两个日期之间的工作天数、计算—年中周内各日期出现次数、确定当前记录和下一条记录之间相差的天数
【SQL开发实战技巧】系列(十八):数据仓库中时间类型操作(进阶)INTERVAL、EXTRACT以及如何确定一年是否为闰年及周的计算
【SQL开发实战技巧】系列(十九):数据仓库中时间类型操作(进阶)如何一个SQL打印当月或一年的日历?如何确定某月内第一个和最后—个周内某天的日期?
【SQL开发实战技巧】系列(二十):数据仓库中时间类型操作(进阶)获取季度开始结束时间以及如何统计非连续性时间的数据
【SQL开发实战技巧】系列(二十一):数据仓库中时间类型操作(进阶)识别重叠的日期范围,按指定10分钟时间间隔汇总数据
【SQL开发实战技巧】系列(二十二):数仓报表场景☞ 从分析函数效率一定快吗聊一聊结果集分页和隔行抽样实现方式
【SQL开发实战技巧】系列(二十三):数仓报表场景☞ 如何对数据排列组合去重以及通过如何找到包含最大值和最小值的记录这个问题再次用执行计划给你证明分析函数性能不一定高
【SQL开发实战技巧】系列(二十四):数仓报表场景☞通过案例执行计划详解”行转列”,”列转行”是如何实现的
【SQL开发实战技巧】系列(二十五):数仓报表场景☞结果集中的重复数据只显示一次以及计算部门薪资差异高效的写法以及如何对数据进行快速分组
【SQL开发实战技巧】系列(二十六):数仓报表场景☞聊聊ROLLUP、UNION ALL是如何分别做分组合计的以及如何识别哪些行是做汇总的结果行
【SQL开发实战技巧】系列(二十七):数仓报表场景☞通过对移动范围进行聚集来详解分析函数开窗原理以及如何一个SQL打印九九乘法表
【SQL开发实战技巧】系列(二十八):数仓报表场景☞人员分布问题以及不同组(分区)同时聚集如何实现
【SQL开发实战技巧】系列(二十九):数仓报表场景☞简单的树形(分层)查询以及如何确定根节点、分支节点和叶子节点
【SQL开发实战技巧】系列(三十):数仓报表场景☞树形(分层)查询如何排序?以及如何在树形查询中正确的使用where条件
【SQL开发实战技巧】系列(三十一):数仓报表场景☞分层查询如何只查询树形结构某一个分支?如何剪掉一个分支?
【SQL开发实战技巧】系列(三十二):数仓报表场景☞对表中某个字段内的值去重
【SQL开发实战技巧】系列(三十三):数仓报表场景☞从不固定位置提取字符串的元素以及搜索满足字母在前数字在后等条件的数据
【SQL开发实战技巧】系列(三十四):数仓报表场景☞如何对数据分级并行转为列
【SQL开发实战技巧】系列(三十五):数仓报表场景☞根据条件返回不同列的数据以及Left /Full Join注意事项
【SQL开发实战技巧】系列(三十六):数仓报表场景☞整理垃圾数据:查找数据的连续性时间和重叠时间的关系,初始化开始结束时间
【SQL开发实战技巧】系列(三十七):数仓报表场景☞从表内始终只有近两年的数据,要求用两列分别显示其中一年的数据聊行转列隐含信息的重要性
【SQL开发实战技巧】系列(三十八):数仓报表场景☞拆分字符串进行连接
【SQL开发实战技巧】系列(三十九):Oracle12C常用新特性☞新增分页查询



前言

在12c之前的查询,如果要返回查询的前N条记录,或则对查询进行分页显示,需要使用rownum伪例,对查询结果进行排序。在oracle12C中引入了row_limiting_clause短语,可以方便的返回结果集中需要的记录。相关关键词为:offset、 row / rows、 fetch 、frist / next 、 rowcount、 precent 、only 。

【SQL开发实战技巧】这一系列博主当作复习旧知识来进行写作,毕竟SQL开发在数据分析场景非常重要且基础,面试也会经常问SQL开发和调优经验,相信当我写完这一系列文章,也能再有所收获,未来面对SQL面试也能游刃有余~。


新增分页查询

在12c之前的查询,如果要返回查询的前N条记录,或则对查询进行分页显示,需要使用rownum伪例,对查询结果进行排序。
在oracle12C中引入了row_limiting_clause短语,可以方便的返回结果集中需要的记录。

重点关键词

下面是row_limiting_clause短语的相关关键词及解释

案例

下面让我们通过一些案例来体验一下此新特性以及通过它们的执行计划深入理解下。
初始化数据:

create table EMP
(
  id   NUMBER,
  time DATE
);
begin 
  for i in 1..10000000
    loop
      insert into emp values(i,systimestamp-i/24/60/60);
      end loop;
commit;
      end;
insert into emp select * from emp where id between 7 and 10;
insert into emp select id,systimestamp from emp where id =8;
insert into emp select id,systimestamp from emp where id =9;

做下面查询:根据时间排序,取最近的数据中,排名在5-15的数据信息:

analyze table emp compute statistics;
alter system flush buffer_cache;
alter system flush shared_pool;
select *
  from (select rownum rn, id, time
          from (select id, time from emp order by time desc) order1) order2
 where rn between 5 and 15;
RN	ID	TIME
5	1	2018/7/12 14:36:17
6	2	2018/7/12 14:36:16
7	3	2018/7/12 14:36:15
8	4	2018/7/12 14:36:14
9	5	2018/7/12 14:36:13
10	6	2018/7/12 14:36:12
11	7	2018/7/12 14:36:11
12	7	2018/7/12 14:36:11
13	8	2018/7/12 14:36:10
14	8	2018/7/12 14:36:10
15	9	2018/7/12 14:36:09
Elapsed: 00:00:05.38

sql连续执行三次以后,消除硬解析等影响后,执行时间大概为5s多。执行计划为:
【SQL开发实战技巧】系列(三十九):Oracle12C常用新特性☞新增分页查询-LMLPHP
【SQL开发实战技巧】系列(三十九):Oracle12C常用新特性☞新增分页查询-LMLPHP

如果在12C中实现上面案例的功能:

alter system flush buffer_cache;
alter system flush shared_pool;
select id, time
  from emp
 order by time desc offset 4 rows fetch first 11 rows with ties;
ID	TIME
1	2018/7/12 14:36:17
2	2018/7/12 14:36:16
3	2018/7/12 14:36:15
4	2018/7/12 14:36:14
5	2018/7/12 14:36:13
6	2018/7/12 14:36:12
7	2018/7/12 14:36:11
7	2018/7/12 14:36:11
8	2018/7/12 14:36:10
8	2018/7/12 14:36:10
9	2018/7/12 14:36:09
9	2018/7/12 14:36:09
Elapsed: 00:00:01.23

Sql执行多次后,平均耗时1.2s,执行计划如下:
【SQL开发实战技巧】系列(三十九):Oracle12C常用新特性☞新增分页查询-LMLPHP
【SQL开发实战技巧】系列(三十九):Oracle12C常用新特性☞新增分页查询-LMLPHP

与12c之前的相比,12c的分页查询(耗时1.2s)比使用rownum伪例(耗时5.4s)效率高出4s左右。12C的分页查询,执行计划更简单,从11g和12c的Column Projection Information来看,12c的分页查询改写使用了分析函数。
看前面的查询结果,11g的rownum伪例取出来的数是11条,12c取出来的数是12条,这是为什么?再来分析下初始化时候的操作,在初始化表的时候,根据时间降序排序后距离目前日期最近的前15条数据中,id=7-10的数据我们重复插入了一遍,然后又插入了两条id相同,但是time不同的(id=8,9)数据.于是我们想要从结果集中查询的第5-15共11条数结果应该是下面标记的范围,为什么12c把id=9的重复的哪一条数据也加到5-15条的范围。这就是with ties的作用,会把与分页查询取到的最后一条记录重复的记录值也取出放在当前页面中,使用时应该注意。如果想返回同11g的哪个sql查询的结果集只需把with ties改成only。
现在知道,之所以12C的这类语法效率高是由于用分析函数改写了,如果此时手动用分析函数改写此sql再来看下效率:
先再来看下12C语法的效率和执行计划:

select id, time
  from emp
order by time desc offset 4 rows fetch first 11 rows with ties;

	ID TIME
---------- ------------
	 5 22-OCT-18
	 6 22-OCT-18
	 7 22-OCT-18
	 8 22-OCT-18
	 9 22-OCT-18
	10 22-OCT-18
	11 22-OCT-18
	12 22-OCT-18
	13 22-OCT-18
	14 22-OCT-18
	15 22-OCT-18

11 rows selected.

Elapsed: 00:00:02.04

然后改写:

select *
  from (select id, time, rank() over(order by time desc) as rn
          from emp)
 where  rn between 5 and 15;	
ID TIME 		RN
---------- ------------ ----------
	 5 22-OCT-18		 5
	 6 22-OCT-18		 6
	 7 22-OCT-18		 7
	 8 22-OCT-18		 8
	 9 22-OCT-18		 9
	10 22-OCT-18		10
	11 22-OCT-18		11
	12 22-OCT-18		12
	13 22-OCT-18		13
	14 22-OCT-18		14
	15 22-OCT-18		15

11 rows selected.
Elapsed: 00:00:02.02

发现其实效率差距不大,12C的top-N语句只是对使用rownum伪例类型的分页查询用分析函数进行了优化。


总结

提示:这里对文章进行总结:

例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。

04-04 05:42