SQL优化之索引优化

索引优化

1、 分析SQL执行的性能

​ 使用explain关键字可以模拟优化器执行SQL查询语句,从而知道MySQL是如何处理SQL语句的。分析所编写的查询语句或是表结构的性能瓶颈。

具体语法:

EXplain DQL语句;

执行的结果一共包括以下几个字段:

idselect_typetablepartitionstypepossible_keyskeykey_lenrefroesfilteredextra
字段描述
id查询的序列号,是一组数字,用来表示查询中执行select子句或者是操作表的顺序。
select_type表示查询的类型,一般有SIMPLE(简单查询)、PRIMARY(主查询,即外层的查询)、UNION(UNION 中的第二个或者后面的查询语句)、SUBQUERY(子查询中的第一个 SELECT)
table查询所用的表
partitions显示的为分区表命中的分区情况,非分区表该字段为空(null)。5.7以后就是默认项
type连接的类型
possible_keys可能使用的索引
key实际使用的索引
key_len索引字段的长度
rows扫描行的数量
extra执行情况的说明和描述

type连接类型性能由好到差的连接类型为( system —> const -----> eq_ref ------> ref-------> ref_or_null----> index_merge —> index_subquery -----> range -----> index ------>all )

EXTRA属性:

using index :使用覆盖索引时会出现。
 
using where:在查找使用索引的情况下,需要回表去查找所需的数据。
 
using index condition:查找使用了索引,但是需要回表查找数据。
 
using index ; using where:查找使用了索引,且需要的数据都在索引列中,不需要回表查询数据。

2、 防止索引失效

2-1 全值索引

对索引中所有的列都指明值,是做好用的一种避免索引失效的方法。

案例:查询1班身份证号为123456的学生的信息。

1.建立索引:
mysql> create index careId_class_index on admin(careId,class);
Query OK, 0 rows affected
Records: 0  Duplicates: 0  Warnings: 0

2.查看索引:
mysql> show index from admin;
+-------+------------+--------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name           | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+--------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| admin |          0 | PRIMARY            |            1 | id          | A         |           5 | NULL     | NULL   |      | BTREE      |         |               |
| admin |          1 | careId_class_index |            1 | careId      | A         |           5 | NULL     | NULL   |      | BTREE      |         |               |
| admin |          1 | careId_class_index |            2 | class       | A         |           5 | NULL     | NULL   |      | BTREE      |         |               |
+-------+------------+--------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
3 rows in set

3.使用索引
   3.1 不采用全值索引
   mysql> explain select * from admin  where careId = '123456';
+----+-------------+-------+------------+------+--------------------+--------------------+---------+-------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys      | key                | key_len | ref   | rows | filtered | Extra |
+----+-------------+-------+------------+------+--------------------+--------------------+---------+-------+------+----------+-------+
|  1 | SIMPLE      | admin | NULL       | ref  | careId_class_index | careId_class_index | 22      | const |    1 |      100 | NULL  |
+----+-------------+-------+------------+------+--------------------+--------------------+---------+-------+------+----------+-------+
1 row in set
     3.2 采用全值索引
     mysql> explain select * from admin  where class = '1'  and careId = '123456';
+----+-------------+-------+------------+------+--------------------+--------------------+---------+-------------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys      | key                | key_len | ref         | rows | filtered | Extra |
+----+-------------+-------+------------+------+--------------------+--------------------+---------+-------------+------+----------+-------+
|  1 | SIMPLE      | admin | NULL       | ref  | careId_class_index | careId_class_index | 44      | const,const |    1 |      100 | NULL  |
+----+-------------+-------+------------+------+--------------------+--------------------+---------+-------------+------+----------+-------+

在这里插入图片描述

2-2 最左前缀法则

定义: 如果在索引中包含了多个字段,即采用复合索引时,通常需要遵循最左前缀原则,即查询从索引的最左前列开始,并且不跳过索引中的列。

案例:

​ 1 .索引不是失效

1.创建索引
mysql> create index careId_class_index on admin(careId,class);
2.使用索引
mysql> explain select * from admin  where careId = '123456';


mysql> explain select * from admin  where careId = '123456' and class = '1';

在这里插入图片描述

​ 2.索引失效:没有遵循最左前缀原则,跳过第一个索引的字段。

1.创建索引
mysql> create index careId_class_index on admin(careId,class);
2.使用索引
mysql> explain select * from admin  where class = '1';

在这里插入图片描述

3.如果出现遵循了最左前缀原则,但是后面跳跃了一个字段,则跳跃后的字段索引失效,此时只有最左端的字段的索引起作用。

2-3 比较后失效

​ 在使用范围查找时,后面的索引失效,简言之就是使用比较运算符后的查找条件的索引失效。

案例:

1.创建索引
mysql> create index index_careId_class_age on admin(careId,class,age);
2.使用索引

在这里插入图片描述

可知:前面两个字段careId、class使用了索引,但是age没有使用索引,即比较后索引失效。

2-4 索引列运算失效

​ 在索引包含的列上进行各种运算,会导致进行全表扫描,此时索引失效。

案例:

1.创建索引
mysql> create index name_index on admin(name);
Query OK, 0 rows affected
Records: 0  Duplicates: 0  Warnings: 0
2.使用索引
mysql> explain select * from admin where substring(name,2,1)='o';
结果:此时进行全表扫描

2-5 字符创不加单引号

一般情况下如果一个字符创不加单引号,此时索引会失效,因为对字符串加单引号,MySQL的查询优化器,会自动的进行类型转换,造成索引失效。

案例:

1.加单引号,没有失效

mysql> explain select * from admin where careId = '123456' and class = '1';

在这里插入图片描述

2. 没加单引号,此时没加单引号的索引失效,
mysql> explain select * from admin where careId = '123456' and class = 1;

在这里插入图片描述

2-6 尽量不使用全部查询

即尽量别使用像select * 这样的语句,多使用覆盖查询,也就是索引的字段。如果查询的列多出了建立索引时所用的列,此时也会影响查询的效率。

案例:

1.select *
mysql> explain select * from admin where careId = '123456' and class = '1' and age =18;

在这里插入图片描述

2.超过索引的范围
mysql> explain select name,age from admin where careId = '123456' and class = '1';

在这里插入图片描述

2-7 在条件查询中使用或者(or)关键字时,索引失效。

在使用or进行条件筛选时会使索引失效。

mysql> explain select * from admin where careId = '123456' or class = '1';

在这里插入图片描述

此时可以使用合并查询union来代替

mysql> explain select * from admin where careId = '123456' union all select * from admin where class = '1';

在这里插入图片描述

2-8 在模糊查询like中,分情况

​ 通配符%在前失效,但是在尾部时索引不会失效,即前失后保。

1.通配符在最前端。

mysql> explain select * from admin where name like'%o';

在这里插入图片描述

2.通配符在后端。

mysql> explain select * from admin where name like'j%';

在这里插入图片描述

2-9 判空不一定

判空主要有两个操作运算符:is null 与 is not null,使用判空运算符时主要看数据表在设计时是否可以为空,从而来判断索引是否失效。

2-10 不等号不一定

在使用不等于运算符(!= <>)时可能索引会失效。

mysql> explain select * from admin where careId <> '123456';

在这里插入图片描述

mysql> explain select * from admin where admin.careId = '123456';

在这里插入图片描述

2-11 多使用复合索引

当多个字段需要建立索引时此时就可以使用复合索引,即建立一个索引相当于建立了好几个索引。

创建复合索引:
mysql> create index deptno_sal_index on emp(deptno,sal);
   
   相当于建立了两个索引:
                   deptno
                   deptno + sal
                   
创建单列索引:
mysql> create index deptno_index on emp(deptno);
mysql> create index sal_index on emp(sal);

在使用索引时,数据库会选择一个最优的索引(辨识度最高索引)来使用,并不会使用全部索引 。

--------------------------------------END------------------------------------

数据库索引基础:----------------------------------------------------《加载完成》------------------------------------------------------------------------------
欢迎关注,谢谢

  • 6
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值