关于SQL优化(面试重点)

42 篇文章 8 订阅
10 篇文章 0 订阅

SQL优化

1、为什么要SQL优化?

随着软件技术的不断发展,系统性能越来越重要。

造成SQL语句性能不佳大概有两个原因:

1、开发人员只关注查询结果的正确性,而忽视了查询语句的效率。

2、开发人员只关注SQL语句本身的效率,对SQL语句执行原理、影响SQL执行效率的主要因素不清楚。

2、什么叫好的SQL语句?

  • 尽量简单化,模块化
  • 易读,易维护
  • 节省资源:比如(CPU、内存、避免全盘扫描、少排序)
  • 不造成死锁

3、实现SQL优化有哪些方法吗?

3.1 避免复杂的多表联查

3.2 避免使用"*"

当你想要检索表中所有的列时,SELECT * FROM TABLE;确实是一个非常方便的方法,但是它的执行效率非常低,实际上,ORACLE在解析的过程中,需要通过查询数据字典,将“*”依次转换成所有的列名,这一步操作呢意味着会消耗更多的时间。

3.3 避免使用耗费资源的操作

带有 DISTINCTUNION、 MINUS、 INTERSECTORDER BYSQL语句会启用SQL引擎执行耗费资源的排序功能,以上  DISTINCT 需要一次排序操作,而其他的至少需要执行两次排序。
通常,带有 UNION、 MINUS、 INTERSECTORDER BYSQL语句都可以用其他方法重写。

3.4 用 EXISTS 替换 DISTINCT

例如:
低效率:
SELECT DISTINCT DEPTNO,DNAME FROM DEPT D,EMP E WHERE D.DEPTNO = E.DEPTNO;
高效率:
SELECT DEPTNO,DNAME FROM DEPT D WHERE EXISTS (SELECT 'X' FROM EMP E WHERE E.DEPTNO = D.DEPTNO);

3.5 用 UNION ALL 替换 UNION

档SQL需要UNION俩个查询结果集时。这俩个结果集会以UNION ALL 的方式被合并,然后再输出最终结果前进行排序。

3.6 创建索引,根据索引查询

举个例子:
假设我的表中有10条数据,我要查询id为8的数据, SELECT * FROM TABLE WHERE ID = 8;
再没索引的情况下,以上的SQL语句最坏的结果可能会从头遍历一次查询8次。
而索引呢,是B-Tree 结构,以二分查法去查询数据。当我对我的id列创建索引后,如下图:
先判读 8 属于 1-5 的范畴,还是 6-10 的范畴,

在这里插入图片描述

也就是说,当我为id创建索引后,那么会先判断 ID = 8 属于 1-5 还是 6-10 ,进入 6-10 后,再判断输入 6-7还是 8-9 还是 10,进入 8-9,则拿到 id=8的数据了。这样它的执行效率远比普通列要快。

3.7 避免再索引列上进行计算

where子句中,如果索引列是函数的一部分。优化器将不会使用索引,而使用全表扫描。

3.8 避免再索引列上使用NOT

3.9 避免使用前置通配符

SELECT * FROM WHERE ENAME LIKE '%R';
这种情况下,ORACLE将使用全盘扫描。

3.10 避免再索引列上使用 IS NULL 和 IS NOT NULL

因为空值不存在索引列中,所以 WHERE子句中对索引列进行空值比较将使 ORACLE停用该索引

3.11 减少访问数据库的次数

3.12 使用DECODE来减少处理时间

3.13 用WHERE替换HAVING子句

sql语句的执行顺序:
from --> 
where -->
group by -->
having -->
order by

3.14 用NOT EXISTS替代 NOT IN

在子查询中,NOT IN 子句将执行一个内部的排序和合并。无论在哪种情况下,NOT IN都是最低效的(因为它对子查询中的表执行了一个全表遍历)。使用NOT EXISTS子句可以有效地利用索引。尽可能使用NOT EXISTS来替代NOT IN,尽管二者都使用了NOT (不能使用索引而降低速度),NOT EXISTS要比NOT IN 查询效率跟高。
例1select dname,deptno from dept where deptno not in(SELECT deptno from emp);2select dname,deptno from dept where not exists(select deptno from emp where dept.deptno = emp.deptno);

如上:
	例2要比例1的执行性能好很多。
	因为1中对emp进行了全表扫描,这是很浪费时间的操作。而且1中没有用到emp的index,因为没有where子句。而2中的语句对emp进行的是缩小范围的查询。

3.15 用>=替代>

例如:
	select * from emp where deptno >= 4;select * from emp where deptno > 3;
以上第一条的效率要比第二条的效率高,因为第一条在执行的时候是直接锁定 4 的,然后再往后查询,而第二条需要先排查前3条,再往后查询。

3.16 尽量多使用commit

事务是消耗资源的,大事务还容易引起死锁。

3.17 用 TRUNCATE替代DELETE

当使用 DELETE 的时候,会产生事务。而 TRUNCATE 则不会。

3.18 关于COUNT()

COUNT()函数的如下,依次降低:
COUNT(索引/主键)
COUNT(*)
COUNT(1)
  • 9
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值