mysql 写出高性能sql 防止索引失效总结

数据库调优步骤:

1)首先查看慢查询日志,找到有问题的 sql 语句   2)利用 explain 查看各个属性的状态   3)利用 show profile  4)查看数据库内部各个关键节点的配置

1、索引是排好序的能够实现快速查找的数据结构,因此对于复合索引来说,mysql会根据创建索引的顺序对数据库表进行排序,因此如果某个sql语句没有按照创建索引的顺序操作字段的话,索引的使用情况必然受到影响,比如创建复合索引 abc,其中 b 没用上,那么本来根据 b 排好序的后面的排序同样也就失效了。索引是存储在磁盘上的一种文件,是和数据库表在物理上分开而逻辑上相连的一种数据结构

where 后跟的是查询条件,order by 后面跟的是排序条件,一般都会在这两者身上用索引,而且这两者都遵循最佳左前缀法则

mysql 支持两种排序方式:1)using index ;2)using filesort,当然要尽量避免后者,尽可能多的使用前者


2、B树不一定都是二叉树,而叫多路搜索树,大多数是B树索引,也有hash索引等其他的索引


3、索引分为:单值索引、唯一索引和复合索引,唯一索引只是加在索引上的一种限制,比如某一个列被
创建成了索引,而且加上了唯一索引的限制(UNIQUE),那么该索引列上的所有的值必须不能重复,都是

唯一的,如果不加唯一索引限制,是可以重复的


4、索引缺点:1、索引也是一张表,占用磁盘空间  2、加上索引提高了数据的搜索速度,但是减慢了
数据的增删改的速度,因为一旦数据表中的数据发生变化,如果变化的列恰好也是索引列,那相应的索引
也要发生更改


5、经常更新的字段不要建索引,重复率太高的字段不要建索引,可以用一个公式来衡量一个列创建索引的选择性:一个列中不同值的数量/该列总记录的数量

6、mysql 是怎么优化的?

执行 EXPLAIN 关键字 + SQL 语句得到:

id   select_type    table    possible_keys     key      key_len     ref     rows     Extra


7、要么别建索引,如果建索引,则group by 的顺序一定要和建索引的顺序相同,来避免产生:Extra 属性里面出现:using filesort 和 using temporary,特别是不要出现后者


8、在范围索引后面的索引是不起作用的(失效索引)


9、左连接的时候,在右表创建索引,右连接的时候,在左表创建索引,如:
select * from employee LEFT JOIN dept on employee.deptID = dept.id

(员工表的部门 ID 等于部门表的主键 ID)这是一个左连接,employee 当做左表,dept 当做右表,所以需要在 dept 上创建索引如:alter table ‘dept’ ADD INDEX Y ('id')


10、索引最好建立在需要经常查询的字段中,对于JOIN 的优化,永远用小表驱动大表,也就是小表要在左边,大表在右边


11、优先优化内层子查询,也就是带括号的查询,只有内层查询快了,外层查询才能加速


12、如果用 explain 解析的 sql 语句的 key 属性值为 NULL,则有两种可能,一种是没创建索引第二是虽然创建了索引,但是索引失效


13、对于复合索引(一个表中同时建立的多个索引,如:create INDEX abc on Employee(a,b,c)),口诀是:
带头大哥不能倒:意思就是按索引创建的顺序,第一个被创建的索引列必须要用上,否则后面的索引不论怎么组合或者单独使用都是无效(也叫做最佳左前缀法则)
中间兄弟不能断:意思是不能隔空只用,比如没有用到中间的 b,而是使用的 a 和 c,则 c 索引失效,a 可以正常使用


14、范围之后全失效,比如:
select * from Employee Where name=July AND age>25 AND position=manager
这个 sql 中用到了 age>25 这个范围,所以 mysql 就会在这个索引层进行查找,后面的 position就失效了


15、尽量在索引列内做查询,少用 select *,比如可以用: 
select a,b from Employee Where name=July AND age>25 AND position=manager


16、当使用不等于符号(!=或者<>)或者is NULL,或者 is not NULL的时候,会导致索引失效,全表扫描

****覆盖索引:查询的时候,选择的查询字段与创建复合索引的字段的名称相同,如果在查询的时候,查询字段的顺序和创建覆盖索引的顺序不一样,索引也能够正常使用,由于在 mysql 架构的第二层有一个优化器,会自动把顺序调整过来,所以一般要按照创建复合索引的顺序写查询字段,避免了一次数据库内部优化的过程,比如:

create INDEX abcd on Employee(a,b,c,d);

select   a,b,c,d   from Employee Where a=1,b=2,c=2,d=0 和 select    a,b,c,d    from Employee Where a=1,b=2,d=0,c=2

这两条 sql 的 explain 结果是相同的,只是第二条 sql 在 mysql 内部做了一次优化,先把 Where 后面的顺序根据创建复合索引的顺序排好 


17、like 查询最好把 % 加在右边:百分like加右边,而且查询的explain 属性 type 值为 range ,否则,加在左边或者两边都加,索引会失效,如果非要在两边加 % 才能保证数据的准确性,则需要创建覆盖索引才能达到索引不失效,所谓覆盖索引,也就是查询的时候,选择的查询字段与创建复合索引的字段的名称相同,当然选择复合索引的其中某几个作为查询字段,索引也不会失效,但是如果是 select * 或者是查询的字段中包含非复合索引字段,则创建的复合索引会失效,比如:
create INDEX abc on Employee (a,b,c);
select a,b,d from Employee Where name like %aa%;
其中 d 字段不是复合索引中的字段,因此该查询仍然是全表扫描,索引失效


18、字符串不加单引号索引会失效,比如:
select * from Employee Where name='2000',该 sql 的索引不会失效,但是如果2000上不加单引号,虽然能够查到结果,(mysql 在内部做了一个隐式的转换,把int型转为 string 型),但是索引会失效


19、少用 or,用 or 也会导致索引失效


20、使用 order by 防止索引失效和防止产生 filesort 的方法,提高 order by 的速度:



21、最佳左前缀法则


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Micrle_007

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值