MySql 索引优化

上一篇MySql 之EXPLAIN 关键字

    在了解EXPLAIN 关键字之后呢,我们就可以根据一些属性查看我们的SQL 语句是否是高效的,从而使我们编写出高效的SQL 语句,接下来就是一些实际应用啦。我在这里建立了一张表并存放了一些数据(建立了一个复合索引)。执行查询SQL 语句,共有三条记录:
这里写图片描述

    查看建立的索引:
这里写图片描述


最佳左前缀原则:

    下面我们使用执行查询语句,这里我们只使用了一个索引字段username,可以看出使用到了我们创建的索引,并且type 为ref,ref 为一个const。
这里写图片描述

    下面我们使用两个索引字段,通过结果可以看出同样使用了索引,并且ref 的变为了两个const,随着查询条件的增多,key_len 的长度变大,说明查询消耗的资源也就相对多一些。
这里写图片描述

    当我们使用三个索引字段的时候呢? 同样使用了索引,并且随着查询条件的变多,key_len 会变得更大,ref 也变为了三个const。
这里写图片描述

    也许细心的你已经发现上面的查询条件顺序是按照创建索引的顺序进行的,尽管并没有完全用到创建索引的字段,但是在查询时,仍然使用到了索引。如果我们不按照创建索引的顺序进行查询呢?下面两个查询语句都没有用到username 字段,在三个索引字段中它是最前面的那个,当我们忽略它时发现我们的查询语句并没有用到索引,我们创建的索引索引失效了,type 也由 ref 变成了ALL 全表扫描,rows 也由1 变成了3。这显然不是我们希望的那样。
这里写图片描述
这里写图片描述

    如果我们使用了username 字段并且跳过了中间的那个字段又会是什么样的呢?会不会使用我们创建的索引呢?可以看出确实使用了我们创建的索引type 为ref,但是key_len 是768,ref 是一个const,而不是两个const,说明并没有使用创建索引的全部字段,只是使用了username 字段,而sex字段并没有使用索引。但是这种情况在某种程度上比上面那种情况要好一些吧?但是作为程序猿我们肯定想要按照我们创建索引的方式使用我们的索引。因此这种方式使用索引并不是最佳的。
这里写图片描述

因此我们在使用索引的时候要遵循最佳左前缀原则,什么是最佳左前缀原则呢?
    最佳左前缀原则:当我们创建了的索引包括多列,查询的顺序应该是从索引的最前端开始,并且不要跳过索引中的其他列。

不要在索引列上做计算,函数等操作:

    如果我们在索引列上操作MySql 的一些函数呢还会按照索引查询我们的数据吗?下面执行了一个left(attribute,len)函数,为了知道left 函数是什么,我做了两次查询,想必聪明的你一定知道是什么意思了吧。
这里写图片描述
这里写图片描述
    知道了left 函数是什么意思后,我们就用EXPLAIN 执行以下它吧,它会使用我们创建的索引吗?根据执行结果可以看出,并没有使用创建的索引,type 为ALL 全表扫描,rows 为3。
这里写图片描述
    所以在我们使用索引时不要在索引列上做任何的操作(这些操作包括:计算,函数等),它会使索引失效,转向全表扫描查找数据。

不要在索引上做范围操作:

    如果我们在索引列上做范围条件筛选会发生什么呢?可以看出type 由ref 变为了range(如果你不清楚这些属性是什么意思,请看博主MySql 中关于EXPLAIN 属性的j介绍),但是使用了我们的索引,key_len = 773,不是1541 说明并没做全部使用索引字段查询,只是使用了username 字段和age 字段。
这里写图片描述
    如果我们的业务需要用到条件范围筛选,那么我们就不要在该字段上创建索引。

在查询时尽量覆盖索引列,少使用SELECT * …:

    当我们在查询数据时,如果不使用SELECT * ..,而是覆盖索引列,那么查询效率是不是会高一些呢?看看执行结果,与SELECT *… 相对比,key_len 的长度是不变的,唯一有变化的是Extra ,由NULL 变成了Using index,当Extra 中出现Using index 时说明我们编写的SQL 是很高效的。
这里写图片描述
这里写图片描述
    即当我们编写SQL 查询语句时,根据业务需求,如果不是要查询所有的字段那么我们就尽量少的使用SELECT * …. 查询语句。

不要在索引上使用 != 、 <> 、 IS NULL 、 IS NOT NULL:

    如果我们使用了会怎么样呢?答案就是在查询数据时不会使用到索引key 为NULL,type 是ALL 全表查找数据,导致索引失效。
这里写图片描述
    所以我们不要在索引上使用 != 、 <> 、 IS NULL 、 IS NOT NULL 进行筛选,这样会导致索引失效。

模糊查询”%” 放关键字右边:

    有的时候我们的需求需要做模糊查询,那么模糊查询使用索引时要注意什么呢?首先我们在关键字两边都加% 进行查询。可以看出没有使用索引。
这里写图片描述
    如果在关键字左边加% 呢?答案是也没有使用索引。
这里写图片描述
    那如果在关键字右边加% 呢?这时type 由上面的ALL 变为了range ,并且也是用到了索引。
这里写图片描述
    所以在能保证工作需求的情况下,当我们遇到这种情况时,要将% 放在关键字的右边。但是如果将% 放在右边并不能完成业务的需求,那又要怎么办呢?
    当查询的数据是索引列时,使用到了索引。
这里写图片描述
这里写图片描述
    当查询的数据既有索引列又有非索引列时,type 为ALL, key 为NULL, 没有使用索引。
这里写图片描述
    由结果可以得出当使用”% + 关键字“可以完成我们的业务需求时,此时我们就使用”% + 关键字“,因为它使用了索引。当”% + 关键字” 不能满足需求的时候,那么我们查询的数据要覆盖索引列(当然也可以包含主键),但是覆盖索引列时不要添加不是索引的列,这样会使索引失效。

字符串类型的索引不要忘记加引号:

    这里就不测试了,意思是如果我们的字段是字符串类型的,并且有的值为数字,那么我们在不加引号的时候也可以通过该字段查到数据,因为MySql 会自动给我们转换类型。但是我们在使用索引的时候,上面的操作是不会使用索引的。

少使用OR:

    下面我们就用OR 连接查询条件看看执行结果,从下图可以看出索引失效了,type 是ALL 全表扫描数据。
这里写图片描述
    在我们编写SQL 语句时,要尽量避免这样的情况出现。

下一篇:MySql ORDER BY 索引优化

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值