mysql优化方案总结(二)

1.什么是索引

索引的优势

从IO和CPU两个方面,使得查询更加快速,减少磁盘IO

索引的劣势

2.mysql索引分类

1.普通索引index :加速查找

2.唯一索引

    主键索引:primary key :加速查找+约束(不为空且唯一)

    唯一索引:unique:加速查找+约束 (唯一)

3.联合索引

    -primary key(id,name):联合主键索引

    -unique(id,name):联合唯一索引

    -index(id,name):联合普通索引

4.全文索引fulltext :用于搜索很长一篇文章的时候,效果最好。

5.空间索引spatial :了解就好,几乎不用

3.索引失效问题汇总

mysql优化方案总结(二)_第1张图片

1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。

2.NULL值会导致索引失效

应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如:   

select id from t where num is null

可以在num上设置默认值0,确保表中num列没有null值,然后这样查询:  

select id from t where num=0

3.应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。

4.应尽量避免在 where 子句中使用 or 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描,如:      

select id from t where num=10 or num=20  

可以这样查询:   

select id from t where num=10    

union all 

select id from t where num=20

5.in 和 not in 也要慎用,否则会导致全表扫描,如: 

select id from t where num in(1,2,3)   

对于连续的数值,能用 between 就不要用 in 了:      

select id from t where num between 1 and 3

7.应尽量避免在 where 子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描。如:     

select id from t where num/2=100

应改为:  

select id from t where num=100*2

8.应尽量避免在where子句中对字段进行函数操作,这将导致引擎放弃使用索引而进行全表扫描。如:

select id from t where substring(name,1,3)='abc'--name以abc开头的id  

应改为:  

select id from t where name like 'abc%' ;

注意:如果在业务上不可避免的需要采用"%xxx%",这时候可以使用locate函数或者position函数替代like查询;

9.不要在 where 子句中的“=”左边进行函数、算术运算或其他表达式运算,否则系统将可能无法正确使用索引。

10.符合索引中曾阶梯状的引用规则,中间断层会导致后续索引失效;

11.在使用索引字段作为条件时,如果该索引是复合索引,那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引,      

否则该索引将不会被使用,并且应尽可能的让字段顺序与索引顺序相一致。

12.很多时候用 exists 代替 in 是一个好的选择:  

select num from a where num in(select num from b)  

用下面的语句替换:   

select num from a where exists(select 1 from b where num=a.num)  

13.并不是所有索引对查询都有效,SQL是根据表中数据来进行查询优化的,当索引列有大量数据重复时,SQL查询可能不会去利用索引,   

如一表中有字段sex,male、female几乎各一半,那么即使在sex上建了索引也对查询效率起不了作用。

14.索引并不是越多越好,索引固然可以提高相应的 select 的效率,但同时也降低了 insert 及 update 的效率,     

因为 insert 或 update 时有可能会重建索引,所以怎样建索引需要慎重考虑,视具体情况而定。

一个表的索引数最好不要超过6个,若太多则应考虑一些不常使用到的列上建的索引是否有必要。

15.尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型,这会降低查询和连接的性能,并会增加存储开销。      

这是因为引擎在处理查询和连接时会逐个比较字符串中每一个字符,而对于数字型而言只需要比较一次就够了。

16.尽可能的使用 varchar 代替 char ,因为首先变长字段存储空间小,可以节省存储空间,      

其次对于查询来说,在一个相对较小的字段内搜索效率显然要高些。      

17.任何地方都不要使用 select * from t ,用具体的字段列表代替“*”,不要返回用不到的任何字段。

18.避免频繁创建和删除临时表,以减少系统表资源的消耗。

19.临时表并不是不可使用,适当地使用它们可以使某些例程更有效,例如,当需要重复引用大型表或常用表中的某个数据集时。但是,对于一次性事件,最好使用导出表。

20.在新建临时表时,如果一次性插入数据量很大,那么可以使用 select into 代替 create table,避免造成大量 log ,    

以提高速度;如果数据量不大,为了缓和系统表的资源,应先create table,然后insert。

21.如果使用到了临时表,在存储过程的最后务必将所有的临时表显式删除,先 truncate table ,然后 drop table ,这样可以避免系统表的较长时间锁定。

22.尽量避免使用游标,因为游标的效率较差,如果游标操作的数据超过1万行,那么就应该考虑改写。  

23.使用基于游标的方法或临时表方法之前,应先寻找基于集的解决方案来解决问题,基于集的方法通常更有效。

25.尽量避免大事务操作,提高系统并发能力。

26.尽量避免向客户端返回大数据量,若数据量过大,应该考虑相应需求是否合理。

27.备注、描述、评论之类的可以设置为 NULL,其他的,最好不要使用NULL。

不要以为 NULL 不需要空间,比如:char(100) 型,在字段建立时,空间就固定了, 不管是否插入值(NULL也包含在内),都是占用 100个字符的空间的,如果是varchar这样的变长字段, null 不占用空间。

4.mysql两种常用引擎

mysql优化方案总结(二)_第2张图片

索引失效行锁变表锁

例如:因为更新记录的时候数据类型使用错误,导致mysql使用自动类型转换,索引失效,而将行锁变为表锁,session 本身更新另一条记录但是却被阻塞;

mysql优化方案总结(二)_第3张图片

注意几点:

1.行锁必须有索引才能实现,否则会自动锁全表,那么就不是行锁了。

2.两个事务不能锁同一个索引。

3.insert delete update在事务中都会自动默认加上排它锁。

 

你可能感兴趣的:(mysql优化)