数据库优化之创建合适的索引

73 阅读4分钟

前言

索引(Index)是帮助DBMS高效获取数据的数据结构。其细分为普通索引、唯一索引、主键索引和全文索引;

  • 普通索引:允许重复的值出现
  • 唯一索引:除了不能有重复的记录外,其它和普通索引一样(用户名、用户身份证、email,tel)
  • 主键索引:是随着设定主键而创建的,也就是把某个列设为主键的时候,数据库就会給改列创建索引。这就是主键索引.唯一且没有null值
  • 全文索引:用来对表中的文本域(char,varchar,text)进行索引, 全文索引针对MyIsam explain select * from articles where match(title,body) against(‘database’);(会使用全文索引);

索然说索引是为了帮助我们更快的解决查询速度的问题,可以提高效率,但是也不是什么情况下都要创建使用索引,如果使用不当则会起到相反的作用。今天我们就来说说索引的具体使用技巧。

索引使用小技巧索引使用小技巧:

索引优缺点:

优点:

①通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性

②大大加快数据的检索速度,这也是创建索引的最主要原因

③加快表与表之间的连接,在实现数据的参考完整性方面特别有意义

④在使用分组和排序,子句进行数据检索时,同样可以显著减少查询中分组和排序的时间

⑤通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统的性能。

缺点:

①创建索引和维护索引需要时间,这种时间随着数据量的增加而增加

②索引需要占物理空间,除了数据表占数据空间之外,每一个索引还要占物理空间,如果要建立聚簇索引,需要的空间更大

③当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,这就降低了数据的维护速度。

使用场景:

a: 肯定在where条件经常使用,如果不做查询就没有意义

b: 该字段的内容不是唯一的几个值(sex)

c: 字段内容不是频繁变化.

具体技巧:

  1. 对于创建的多列索引(复合索引),不是使用的第一部分就不会使用索引。
alter table dept add index my_ind (dname,loc); // dname 左边的列,loc就是右边的列
explain select * from dept where dname='aaa';// 会使用到索引
explain select * from dept where loc='aaa';// 就不会使用到索引
  1. 对于使用like的查询,查询如果是’%aaa’不会使用到索引而‘aaa%’会使用到索引。
 explain select * from dept where dname like '%aaa';//不能使用索引
 explain select * from dept where dname like 'aaa%';//使用索引.

所以在like查询时,‘关键字’的最前面不能使用 % 或者 _这样的字符.,如果一定要前面有变化的值,则考虑使用 全文索引

  1. 如果条件中有or,有条件没有使用索引,即使其中有条件带索引也不会使用。换言之,就是要求使用的所有字段,都必须单独使用时能使用索引.

  2. 如果列类型是字符串,那一定要在条件中将数据使用引号引用起来。否则不使用索引。

expain select * from dept where dname=’111’;
expain select * from dept where dname=111;//(数值自动转字符串)
expain select * from dept where dname=qqq;//报错

也就是,如果列是字符串类型,无论是不是字符串数字就一定要用 ‘’ 把它包括起来.

  1. 如果mysql估计使用全表扫描要比使用索引快,则不使用索引。 如表里面只有一条记录的情况。

mysql索引什么情况下会失效?

  • 在查询条件没有用到索引列。

  • 查询条件中带有or,除非所有的查询条件都建有索引,否则索引失效。

  • like查询是以%开头。

  • 如果列类型是字符串,那在查询条件中需要将数据用引号引用起来,否则不走索引。

  • 联合索引,查询时的条件列不是联合索引中的第一个列,索引失效。

  • is null 可以使用索引,is not null 无法使用索引。

  • 如果左边的值未确定,那么无法使用此索引。

     select * from table where a>1 and b=2;//a不确定,所以ab 的联合索引就用不到。)
    
  • 索引列上参与计算、使用内置函数、类型转换 ( 自动或手动 ) ,会导致索引失效。

  • 如果mysql估计全表扫描要比使用索引要快,会不使用索引。