Sql查询优化

sql语句执行顺序
从右到左、从上到下
1.Oracle的解析器按照从右到左的顺序处理FROM子句中的表名,FROM子句中写在最后的表(基础表 driving table)将被最先处理
2.Oracle采用自下而上的顺序解析WHERE子句,根据这个原理,表之间的连接必须写在其他WHERE条件之前, 那些可以过滤掉最大数量记录的条件必须写在WHERE子句的末尾

优化技巧
1.SELECT子句中避免使用‘*’:
(Oracle在解析的过程中, 会将‘*’依次转换成所有的列名, 这个工作是通过查询数据字典完成的, 这意味着将耗费更多的时间)
2.用Where子句替换HAVING子句:(on是最先执行,where次之,having最后)
(避免使用HAVING子句,HAVING 只会在检索出所有记录之后才对结果集进行过滤。这个处理需要排序,总计等操作。如果能通过WHERE子句限制记录的数目,那就能减少这方面销)
3.使用表的别名(Alias):
(当在SQL语句中连接多个表时, 请使用表的别名并把别名前缀于每个Column上。这样一来,就可以减少解析的时间并减少那些由Column歧义引起的语法错误。)
4.用EXISTS替代IN、用NOT EXISTS替代NOT IN:
(EXISTS 使查询更为迅速,因为RDBMS核心模块将在子查询的条件一旦满足后,立刻返回结果,NOT IN都是最低效的 (因为它对子查询中的表执行了一个全表遍历))
eg.
(高效)SELECT * FROM EMP (基础表) WHERE EMPNO > 0 AND EXISTS (SELECT ‘X’ FROM DEPT WHERE DEPT.DEPTNO = EMP.DEPTNO AND LOC = ‘MELB’)
(低效)SELECT * FROM EMP (基础表) WHERE EMPNO > 0 AND DEPTNO IN(SELECT DEPTNO FROM DEPT WHERE LOC = ‘MELB’)
5.用EXISTS替换DISTINCT:
eg
(低效): SELECT DISTINCT DEPT_NO,DEPT_NAME FROM DEPT D , EMP E WHERE D.DEPT_NO = E.DEPT_NO
(高效): SELECT DEPT_NO,DEPT_NAME FROM DEPT D WHERE EXISTS ( SELECT ‘X’ FROM EMP E WHERE E.DEPT_NO = D.DEPT_NO);
6.SQL语句用大写的;
(因为Oracle总是先解析SQL语句,把小写的字母转换成大写的再执行。)
7。
(1)避免在索引(查询效率高,但是牺牲了存储空间)列使用not,<>、!=进行计算、这样会导致停止使用索引转而执行全表扫描.、
(2)UNION替换OR
(3)避免在索引列上使用IS NULL和IS NOT NULL:
(Oracle将无法使用空索引列,如果列包含空值,索引中将不存在此记录)
(4)避免改变索引列的类型、使用函数:
(当比较不同数据类型的数据时, ORACLE自动对列进行简单的类型转换。这个索引将不会被用到!)
eg.SELECT … FROM EMP WHERE EMPNO = ‘123’自动转换为SELECT … FROM EMP WHERE EMP_TYPE = 123
(5)带通配符(%)的like语句中%出现在词首会不使用索引:
(这里由于通配符(%)在搜寻词首出现,所以Oracle系统不使用last_name的索引。)
8.用>=替代>:
(前者DBMS将直接跳到第一个DEPT等于4的记录而后者将首先定位到DEPTNO=3的记录并且向前扫描到第一个DEPT大于3的记 录)
eg.高效:SELECT * FROM EMP WHERE DEPTNO >=4 低效: SELECT * FROM EMP WHERE DEPTNO >3
9.用IN来替换OR:
低效:
SELECT…. FROM LOCATION WHERE LOC_ID = 10 OR LOC_ID = 20 OR LOC_ID = 30
高效:
SELECT… FROM LOCATION WHERE LOC_IN IN (10,20,30);
10.应尽量避免在where子句中对字段进行函数操作,这将导致引擎放弃使用索引而进行全表扫描
eg.
select id from t where substring(name,1,3) = ’abc’
改为
select id from t where name like ‘abc%’
11.拆分大的 DELETE 或INSERT 语句,批量提交SQL语句
(如果你需要在一个在线的网站上去执行一个大的 DELETE 或 INSERT 查询,你需要非常小心,要避免你的操作让你的整个网站停止相应。因为这两个操作是会锁表的,表一锁住了,别的操作都进不来了。)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值