MySQL优化之索引的使用

目录

索引的使用场景

哪些列适合建立索引

联合索引

索引优化SQL的方法

使用索引时的注意事项 


​​​​​​​

索引的使用场景

1、表的主关键字
2、自动建立唯一索引
3、表的字段唯一约束
4、直接条件查询的字段(在 SQL 中用于条件约束的字段)
5、查询中与其它表关联的字段
6、查询中排序的字段(排序的字段如果通过索引去访问那将大大提高排序速度)
7、查询中统计或分组统计的字段

8、表记录太少(如果一个表只有 5 条记录,采用索引去访问记录的话,那首先需访问索引表,再通过索引表访问数据表,一般索          引表与数据表不在同一个数据块)
9、经常插入、删除、修改的表(对一些经常处理的业务表应在查询允许的情况下尽量减少索引)
10、数据重复且分布平均的表字段(假如一个表有 10 万行记录,有一个字段 A 只有 T 和 F 两种值,且每个值的分布概率大约为            50%,那么对这种表 A 字段建索引一般不会提高数据库的查询速度。)
11、经常和主字段一块查询但主字段索引值比较多的表字段
12、对千万级 MySQL 数据库建立索引的事项及提高性能的手段 

哪些列适合建立索引

1、在 where 从句,group by 从句,order by 从句,on 从句中的列添加索引
2、索引字段越小越好(因为数据库数据存储单位是以“页”为单位的,数据存储的越多,IO 也会越大

3、离散度大的列放到联合索引的前面

select * from payment where staff_id =2 and customer_id =584;

对面上面的SQL建立联合索引应该把那个列放前面呢?

分别查看这两个字段中不同的 id 的数量,数量越多,则表明离散程度越大:因此可以通过下图看出:customer_id 离散程度大 

结论:由于 customer_id 离散程度大,使用 index(customer_id,staff_id)好

联合索引

命名规则

1、需要加索引的字段,要在 where 条件中
2、数据量少的字段不需要加索引
3、如果 where 条件中是 OR 关系,加索引不起作用
4、符合最左原则

 什么是联合索引

1、 两个或更多个列上的索引被称作联合索引,又被称为是复合索引。
2、 利用索引中的附加列,您可以缩小搜索的范围,但使用一个具有两列的索引 不同于使用两个单独的索引。创建复合索引时,应该仔细考虑列的顺序。对索引中的所有列执行搜索或仅对前几列执行搜索时,复合索引非常有用;仅对后面的任意列执行搜索时,复合索引则没有用处。

索引优化SQL的方法

1、索引的维护及优化(重复及冗余索引)
增加索引会有利于查询效率,但会降低 insert,update,delete 的效率,但实际上往往不是这样的,过多的索引会不但会影响使用效率,同时会影响查询效率,这是由于数据库进行查询分析时,首先要选择使用哪一个索引进行查询,如果索引过多,分析过程就会越慢,这样同样的减少查询的效率,因此我们要知道如何增加,有时候要知道维护和删除不需要的索引

2、如何找到重复和冗余的索引

  • 重复索引:

重复索引是指相同的列以相同的顺序建立的同类型的索引,如下表中的 primary key 和ID 列上的索引就是重复索引

create table test(
id int not null primary key,
name varchar(10) not null,
title varchar(50) not null,
unique(id)
)engine=innodb;
  • 冗余索引:

冗余索引是指多个索引的前缀列相同或是在联合索引中包含了主键的索引,下面这个例子中 key(name,id)就是一个冗余索引

create table test(
id int not null primary key,
name varchar(10) not null,
title varchar(50) not null,
key(name,id)
)engine=innodb;

3.使用 pt-duplicate-key-checker 工具查找重复索引

pt-duplicate-key-checker -uroot -padmin -h 127.0.0.1

 

4.索引维护的方法
由于业务变更,某些索引是后续不需要使用的,就要进行删除。在 mysql 中,可以通过慢查询日志配合 pt-index-usage 工具来进行索引使用情况的分析;

pt-index-usage -uroot -padmin /var/lib/mysql/mysql-host-slow.log

使用索引时的注意事项 


1,创建索引
很多时候性能问题很简单的就是因为我们忘了添加索引而造成的,或者说没有添加更为有效的索引导致。如果不加索引的话,那么查找任何哪怕只是一条特定的数据都会进行一次全表扫描,如果一张表的数据量很大而符合条件的结果又很少,那么不加索引会引起致命的性能下降。但是也不是什么情况都非得建索引不可,比如性别可能就只有两个值,建索引不仅没什么优势,还会影响到更新速度,这被称为过度索引。 

2,复合索引
比如有一条语句是这样的:select * from users where area=’beijing’ and age=22;
如果我们是在 area 和 age 上分别创建单个索引的话,由于 mysql 查询每次只能使用一个索引,所以虽然这样已经相对不做索引时全表扫描提高了很多效率,但是如果在 area、age 两列上创建复合索引的话将带来更高的效率。如果我们创建了(area, age,salary)的复合索引,那么其实相当于创建了(area,age,salary)、(area,age)、(area)三个索引,这被称为最佳左前缀特
性。因此我们在创建复合索引时应该将最常用作限制条件的列放在最左边,依次递减。


3,索引不会包含有 NULL 值的列
只要列中包含有 NULL 值都将不会被包含在索引中,复合索引中只要有一列含有 NULL 值,那么这一列对于此复合索引就是无效的。所以我们在数据库设计时不要让字段的默认值为NULL。


4,使用短索引
对字符串列进行索引,如果可能应该指定一个前缀长度。例如,如果有一个 CHAR(255)的 列,如果在前 10 个或 20 个字符内,多数值是惟一的,那么就不要对整个列进行索引。短索引不仅可以提高查询速度而且可以节省磁盘空间和 I/O 操作。


5,排序的索引问题
mysql 查询只使用一个索引,因此如果 where 子句中已经使用了索引的话,那么 order by 中的列是不会使用索引的。因此数据库默认排序可以符合要求的情况下不要使用排序操作;尽量不要包含多个列的排序,如果需要最好给这些列创建复合索引。


6,like 语句操作
一般情况下不鼓励使用 like 操作,如果非使用不可,如何使用也是一个问题。like “%aaa%” 不会使用索引而 like “aaa%”可以使用索引。


7,不要在列上进行运算
select * from users where YEAR(adddate)   ×


8,不使用 NOT IN 操作
NOT IN 操作都不会使用索引将进行全表扫描。NOT IN 可以 NOT EXISTS 代替

发布了568 篇原创文章 · 获赞 180 · 访问量 18万+

猜你喜欢

转载自blog.csdn.net/Delicious_Life/article/details/105610256