MySql优化

一、常见优化规则

1、表连接数

1)连接的表越多,性能越差

2)可能的话,将连接拆分成若干个过程逐一查询

3)优先执行可显著减少数据量的连接,既降低复杂度,也能够 容易按照预期执行

4)如果不避免多表连接,很可能是设计缺陷

5)外链接效果差,因为必须对左右表进行表扫描

6)尽量使用inner join查询

2、尽量使用临时表

如果不可避免,可以考虑使用临时表或表变量存放中间结果

3、少用子查询

4、视图嵌套:不要过深,一般视图嵌套不要超过2个为宜

5、SQL编写注意事项

1)NULL列

NULL列使用索引没有意义,任何包含null值的列都不会被包含到索引中。因此where语句中的is null或is not null的语句优化器是不允许使用索引的。

2)CONCAT或||

concat或||是mysql和Oracle的字符串连接操作,如果对列进行该函数操作,那么也是会忽略索引的使用

-- 忽律索引 select ... from .. where first_name || '' || last_name = 'bill gates' ;

-- 使用索引 select ... from .. where first_name = 'bill' and last_name = 'bill gates' ;

3)like

通配符出现在首位,无法使用索引,反之可以

-- 无法使用索引 select .. from .. where name like '%t%' ;

-- 可以使用索引 select .. from .. where name like 't%' ;

4)order by

order by子句中不要使用非索引列或嵌套表达式,这样都会导致性能降低。

5)Not运算

not运算无法使用索引,可以改成其他能够使用索引的操作。

-- 索引无效 select .. from .. where sal != 3000 ;

-- 索引生效 select .. from .. where sal < 3000 or sal > 3000;

6)where与having

select...from...on..where..group by..having..order by ...limit..,以上是SQL语句的语法结构,其中on,where和having是有过滤行为的,过滤行为越能提前完成就越可以减少传递给下一个阶段的数据量,因此如果在having中的过滤行为能够在where中完成,则应该优先考虑where来实现。

7)exists替代in

not in是最低效的,因为对子查询的表进行全表扫描,可以考虑使用外链接或not exists.如下:

-- 正确 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')

8)索引

索引的好处可以实现折半查找,时间复杂度是O(log2n),但是也有成本,需要额外的空间存放索引数据,并且每次insert、update和delete都会对索引进行更新,因此会增加4,5次的磁盘IO。所以给一些不必要使用索引的字段添加索引,会降低系统的性能。对于Oracle来讲,SQL语句尽量大写,内部需要将小写转成大写,再执行。不要在索引列上使用函数,这样会停止使用索引,进行全表扫描,如下:

-- 错误 SELECT … FROM DEPT WHERE SAL * 12 > 25000;

-- 正确 SELECT … FROM DEPT WHERE SAL > 25000/12;

9)>与>=

-- 直接定位到4的记录(推荐) select .. from .. where SAL >= 4 ;

-- 先定位到3,再向后找1个(不推荐) select .. from .. where SAL > 3 ;

10)union代替or

在索引上,可以使用union替换or操作,索引列上的or操作会造成全表扫描。

-- 高效: SELECT LOC_ID , LOC_DESC , REGION FROM LOCATION WHERE LOC_ID = 10 UNION SELECT LOC_ID , LOC_DESC , REGION FROM LOCATION WHERE REGION = 'MELBOURNE'

-- 低效: SELECT LOC_ID ,LOC_DESC ,REGION FROM LOCATION WHERE LOC_ID=10 OR REGION ='MELBOURNE'

11)is null & is not null

如果列可空,避免使用索引。对于多个列使用的索引,起码保证至少有个列不为空。对于多列索引,只有访问了第一个列才会启用索引,如果访问后面的列则使用的是全表扫描。

-- 低效: (索引失效) SELECT .. FROM DEPARTMENT WHERE DEPT_CODE IS NOT NULL;

-- 高效: (索引有效) SELECT .. FROM DEPARTMENT WHERE DEPT_CODE >=0;

12)union & union all

union具有去重的操作,增加计算空间。union all不需要去重,但会包含相同记录,同样功能下,首选union all操作

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值