2019-05-10
SQL语句
Oracle伪列
伪列并没有存储在表中。伪列值可以查询,但不能插入、更新和删除。
rowid
rowid用于保存表中每条记录的物理地址。每条记录都有唯一的rowid。Oracle自动为每个表建立rowid字段。
// 删除表中重复记录(适用于有少量重复记录的情况)
delete from emp where rowid not in (select min(rowid) from emp group by empno);
rownum
rownum是对查询结果集加的行号。返回的第一行分配的是1,第二行是2,依此类推。如果查询中有order by
语句,rownum是排序前的编号。
// 查询表中小于n的记录,使用条件rownum<n。
select rownum,student.* from student where rownum <3;
// 查询表中第n(n>1)条记录,使用rownum=n作为条件,查询结果为空。
SELECT rownum,student.* FROM student WHERE rownum >=2;
原因:如果用>,>=,=这些条件,因为第一条记录的rownum为1,则可能被即时删除,接着取下条,可是它的rownum还是1,又被删除,依次类推,便没有了数据。
// 解决方案:使用子查询
select * from (select rownum as no,student.* from student) where no>=2;
Oracle分页
Oracle中的分页查询必须使用rownum完成。
假设start为当前页的起始行号,limit为要取到的行数
使用方法:rownum>=start and rownum<start+limit
// 对原始记录分页(假设每页3条记录)
select * from ( select rownum as no,emp.* from emp) where no>=1 and no<4;
select * from ( select rownum as no,emp.* from emp) where no>=4 and no<7;
// 对原始记录排序(雇佣日期降序)后进行分页(假设每页3条记录)
select * from (
select rownum as no,e1.* from(select * from emp order by hiredate desc ) e1) e2
where e2.no>=1 and e2.no<4 ;
select * from (
select rownum as no,e1.* from (select * from emp order by hiredate desc ) e1) e2
where e2.no>=4 and e2.no<7 ;
SQL优化
select语句中避免使用
*
使用where子句替代having子句
使用联合查询而不是子查询
使用exists替代in
from子句优化
Oracle解析器在处理FROM子句中的表时,按照从右到左的顺序, FROM子句中最后指定的表将被Oracle首先处理,Oracle将它作为驱动表(Driving Table),并对该表的数据进行排序;之后再扫描倒数第二个表,将所有从第二个表中检索出来的记录与第一个表中的合适记录进行合并。所以在FROM子句中包含多个表的情况下,放在from语句最后的驱动表是数据最少的表,效率更高。
where子句优化
oracle采用自右至左的顺序解析where子句,根据这个顺序,表之间的连接应该写在其他条件之前,应将可以过滤掉最大数量记录的条件写在where子句的末尾。
避免使用distinct
避免使用order by
利用索引进行优化
表的主、外键应建立索引。
数据量超过300的表应建立索引。
经常与其他表建立连接的表,在连接字段上应建立索引。
在where子句或是连接条件上经常引用的列上建立索引。不带where条件的sql语句是一定不使用索引的,因此不要随意去查询整张表。
where 子句包含not 关键字,执行时该字段的索引失效。应使用比较运算符替换not。
where 子句包含or 操作,执行时不使用索引,可以使用in条件来替换。
where 子句包含like,执行时不使用索引,应尽量避免使用。
在where条件中有索引的字段不能参与运算,否则索引无效,执行全表扫描。