Oracle的练习与优化

来源:互联网 发布:知乎 淘宝办公室零食 编辑:程序博客网 时间:2024/05/29 19:29

Oracle的练习与优化

1.查询工资大于1200的员工姓名和工资 select ename,sal from emp where sal>1200; 2.查询员工号为7900的员工的姓名和部门号  select ename,deptno from emp where empno=7900; 3.选择工资不在2000到3000的员工的姓名和工资   select ename,sal from emp where sal not between  2000 and 3000; 4.选择雇用时间在1981-02-01到1982-05-01之间的员工姓名,job   和雇用时间 select ename,job,hiredate from empwhere hiredate between to_date('1981-02-01','yyyy-MM-dd') and to_date('1982-05-01','yyyy-MM-dd');   5.选择在20或40号部门工作的员工姓名和部门号 select ename,deptno from emp where deptno in(20,40); 6.选择在1981年雇用的员工的姓名和雇用时间select ename,hiredate from emp where extract(year from hiredate)=1981; 7.选择公司中没有管理者的员工姓名及jobselect ename,job from emp where mgr is null; 8.选择公司中有奖金的员工姓名,工资和奖金级别   select ename,sal,comm from emp where nvl(comm,0)!=0; 9.选择员工姓名的第三个字母是a的员工姓名   select ename from emp where  ename like '__A%';   10.选择姓名中有字母a和e的员工姓名  select ename from emp where  ename like '%A%' and ename like '%E%';  11.显示系统时间 select sysdate from dual;  12.查询员工号,姓名,工资,以及工资提高百分之20%后的结果 select empno,ename,sal,(sal*1.2) as 提高后的工资 from emp; 13.将员工的姓名按首字母排序,并写出姓名的长度(length) select ename,length(ename) from emp order by ename; 14.查询各员工的姓名,并显示出各员工在公司入职的月份数 select ename,extract(month from hiredate) from emp; 15.查询员工的姓名,以及在公司入职的月份数(worked_month),并按月份数降序排列 select ename,extract(month from hiredate) from emp order by extract(month from hiredate) desc; 16.查询公司员工工资的最大值,最小值,平均值,总和 select max(sal),min(sal),avg(sal),sum(sal) from emp; 17.查询各工种(job)的员工工资的最大值,最小值,平均值,总和 select job,max(sal),min(sal),avg(sal),sum(sal) from emp group by job;  18.选择各个工种(job)的员工人数select job,count(empno) from emp group by job; 19.查询员工最高工资和最低工资的差距(DIFFERENCE) select max(sal)-min(sal) from emp; 20.查询各个管理者手下员工的最低工资,其中最低工资不能低于1500,没有管理者的员工不计算在内--分析--查询员工select * from emp;select mgr,min(sal) from emp group by mgr having mgr is not null and min(sal)>=1500; 21.查询所有部门的名字,工作地点,员工数量和工资平均值.select * from dept left outer join emp on dept.deptno =emp.deptno; select dept.dname,dept.loc,count(emp.empno),avg(emp.sal) from dept left outer join emp on dept.deptno =emp.deptno group by dname,loc;  22.查询和scott相同部门的员工姓名和雇用日期select deptno from emp where emp.ename='SCOTT'; select ename,hiredate from emp where deptno =(select deptno from emp where emp.ename='SCOTT');--等同select emp.ename,emp.hiredate from emp,(select deptno from emp where emp.ename='SCOTT') tmp where emp.deptno=tmp.deptno; 23.查询工资比公司平均工资高的员工的员工号,姓名和工资。select avg(sal) from emp;select empno,ename,sal from emp;select empno,ename,sal from emp where sal>(select avg(sal) from emp);  24.查询各部门中工资比本部门平均工资高的员工的员工号, 姓名和工资select deptno,avg(sal) from emp group by deptno; select empno,ename,sal from emp; --连表查询select empno,ename,sal, tmp.vagsal,emp.deptno from emp,(select deptno,avg(sal) as vagsal from emp group by deptno) tmpwhere emp.deptno=tmp.deptno and emp.sal>tmp.vagsal;  25.查询和姓名中包含字母u的员工在相同部门的员工的员工号和姓名select ename,deptno from emp where ename like '%U%'; select empno,ename,deptno from emp; --连接表select emp.empno,emp.ename,emp.deptno from emp,(select deptno from emp where ename like '%U%') tmpwhere emp.deptno=tmp.deptno; 26. 查询管理者是King的员工姓名和工资--子查询select empno from emp where ename='KING';--这种写法的前提,名字不能相同select ename,sal,mgr from emp where mgr=(select empno from emp where ename='KING'); 27. 使用PL/SQL实现9*9的乘法口诀表  set serveroutput on;begin  for i in 1..9    loop               for j in 1..i          loop             --不换行使用put             dbms_output.put(i ||'*'||j||'='|| (i*j)||' ');                    end loop;            --换行            dbms_output.new_line();            end loop; end; 


优化

1、 查两张以上表时,把记录少的放在右边

2、 WHERE子句中的连接顺序

ORACLE采用自上而下的顺序解析WHERE子句,根据这个原则,那些可以过滤掉最大数量记录的条件应写在WHERE子句最后  

例如:查询员工的编号,姓名,工资,部门名  

      如果emp.sal>1500能过滤掉半数记录的话,

      select emp.empno,emp.ename,emp.sal,dept.dname

      from emp,dept

      where (emp.deptno = dept.deptno) and (emp.sal > 1500)

             .......  

3、 SELECT子句中避免使用*号

ORACLE在解析的过程中,会将*依次转换成所有的列名,这个工作是通过查询数据字典完成的,这意味着将耗费更多的时间

4、 避免对大表进行无条件或无索引的的扫描

5、 清空表时用TRUNCATE替代DELETE

6、 尽量多使用COMMIT;因为COMMIT会释放回滚点

7、 用索引提高查询效率,善用索引

避免在索引列上使用NOT;因为Oracle服务器遇到NOT后,他就会停止目前的工作,转而执行全表扫描。

避免在索引列上使用计算;WHERE子句中,如果索引列是函数的一部分,优化器将不使用索引而使用全表扫描,这样会变得慢

      例如,SAL列上有索引,

      低效:

      SELECT EMPNO,ENAME

      FROM EMP

      WHERE SAL*12 > 24000;

      高效:

      SELECT EMPNO,ENAME

      FROM EMP

      WHERE SAL > 24000/12;

8、 字符串型,能用=号,不用like=号表示精确比较,like表示模糊比较

9、  >= 替代 >

低效:

      SELECT * FROM EMP WHERE DEPTNO > 3   

      首先定位到DEPTNO=3的记录并且扫描到第一个DEPT大于3的记录

      高效:

      SELECT * FROM EMP WHERE DEPTNO >= 4  

      直接跳到第一个DEPT等于4的记录

10、 IN替代OR

select * from emp where sal = 1500 or sal = 3000 or sal = 800;

select * from emp where sal in (1500,3000,800);

11、 exists代替in;not exists代替 not in

not in 字句将执行一个内部的排序和合并,任何情况下,not in是最低效的,子查询中全表扫描;表连接比exists更高效

12、 UNION-ALL 替换UNION

SQL语句需要UNION两个查询结果集合时,这两个结果集合会以UNION-ALL的方式被合并, 然后在输出最终结果前进行排序. 如果用UNION ALL替代UNION, 这样排序就不是必要了. 效率会因此得到提高。

13、 避免使用耗费资源的操作

带有DISTINCT,UNION,MINUS,INTERSECT的SQL语句会启动SQL引擎 执行耗费资源的排序(SORT)功能. DISTINCT需要一次排序操作, 而其他的至少需要执行两次排序. 通常,带有UNION, MINUS , INTERSECT的SQL语句都可以用其他方式重写。

 

最后;同样的操作有些时候可以在程序上处理的就程序上处理,毕竟在内存中的执行速度比在硬盘上执行要高非常多。

0 0
原创粉丝点击