(一)rownum的概念
ROWNUM是一个序列,会根据sql语句自动给你加上一列排好顺序的序号列。rownum总是为满足条件的记录从1开始设序号,所以rownum总是从1开始的。rownum是根据sql查询出的结果给每行分配一个逻辑编号。
从定义可以理解,rownum只能使用小于等于号。不能使用大于号。
例如找10名以后同学的成绩:当从数据库中找到语文成绩第一名的记录时,设序号为1,该记录不满足rownum>10。所以抛弃该记录,接着从数据库中找到语文成绩第二名的记录,又设序号为1,该记录依然不满足rownum>10,依次类推。所以穷尽整张表抛弃了所有记录。
(二)rownum的用法
对于范围查询可以使用子查询来解决rownum的局限性。需要注意的是:子查询中的rownum必须要有别名,否则还是不会查出记录来,这是因为rownum不是某个表的列,如果不起别名的话,无法知道rownum是子查询的列还是主查询的列。
实例:求薪水最高的第六个人到第十个人
第一种查询语句:(用时:秒级别 ,2秒多)
select ename,sal from
(select ename,sal,rownum r from
(select ename,sal from emp order by sal desc)
) t where t.r between 6 and 10; (这种分页语句查询效率比较低)
第二种分页查询语句:(用时:毫秒级别,几毫秒)推荐使用这种。
- SELECT * FROM
- (
- SELECT A.*, ROWNUM RN
- FROM (SELECT * FROM T1) A
- WHERE ROWNUM <= 40
- )
- WHERE RN >= 21;
对于效率的比较可以参考:点击打开链接
(二)ROWID的用法(用于删除重复的记录)
DELETE FROM hr.employees t1
WHERE t1.ROWID NOT IN (
SELECT MIN(t2.ROWID)
FROM hr.employees t2
GROUP BY t2.employee_id --按照想要唯一保留的字段进行分组
);
这个明显就比方法一好多了,子查询中我们先选除了rowid,然后按照我们想要保留的唯一字段进行分组,并取每组最小的rowid(注意是子查询表的rowid);然后在用not in删除除开最小的rowid以外的所有记录。
参考文档:https://www.cnblogs.com/zhongjiajie/p/5652376.html
(三)多表之间的连接有三种方式:Nested Loops,Hash Join 和 Sort Merge Join.
Hash join的工作方式是将一个表(通常是小一点的那个表)做hash运算,将列数据存储到hash列表中,从另一个表中抽取记录,做hash运算,到hash 列表中找到相应的值,做匹配。
Nested loops 工作方式是从一张表中读取数据,访问另一张表(通常是索引)来做匹配,nested loops适用的场合是当一个关联表比较小的时候,效率会更高。
Merge Join 是先将关联表的关联列各自做排序,然后从各自的排序表中抽取数据,到另一个排序表中做匹配,因为merge join需要做更多的排序,所以消耗的资源更多。 通常来讲,能够使用merge join的地方,hash join都可以发挥更好的性能。