MySQL索引优化小细节

1.当使用索引列进行查询的时候尽量不要使用表达式,把计算放到业务层而不是数据库层

2.尽量使用主键查询,而不是其他索引,因为主键查询不会触发回表

两种主键:

(1)自然主键:和当前业务系统是有关的

(2)代理主键(推荐使用):和当前这个表其他信息,在业务上是没啥关系的,比如设置一个uuid 

3. 使用前缀索引

当我们列的值太长的时候,比如url了,或者城市名字等时候,可惜选择属性值的前n个字符进行建立索引,这里涉及到序偶引得选择性,我们可以进行测试,看看选多少前缀和原本的数据量级是差不多的,这样建立索引才更加合适

例如一张citydemo表中有很多数据,我们要对城市名列建立索引,我们可以查询城市名

seletct count(*) as cnt, city from city from citydemo group by city order by cnt desc limit 10;//这里就可以得到一个量级的数据

10W条数据没有索引_ci

然后我们就可以根据这个名字重复的量级来看看前缀选择多少个字符是合适的

select count(*) as cnt,left(city,7) as pref group by cnt order by cnt dexc limit 10;//选择7个时量级就差不多了

10W条数据没有索引_字段_02

4.使用索引扫描来排序

using filesort表示利用文件排序

如下是rental表的索引情况

10W条数据没有索引_ci_03

如下查询此时reantal_data,inventory_id,customer_id正好是组合索引,所以使用索引排序了

10W条数据没有索引_主键_04

如下查询此时reantal_id,customer_id不符合索引匹配原则,所以使用文件排序了(using filesort)

10W条数据没有索引_10W条数据没有索引_05

5.union all,in,or都会走索引,推荐使用in

6.范围列可以使用到索引

(1)范围条件是:<,<=,>.>=,between

(2)范围列可以用到索引,但是范围列后面的列无法用到索引,索引最多用于一个范围列

7.强制类型转换会全表扫描

explain select * from user where phone=13244445555;//phone是vechar类型,不会触发索引

explain select * from user where phone=‘13244445555’;//phone是vechar类型,会触发索引

8.更新十分频繁,数据区分度不高的字段上不宜建立索引

(1)更新会变更B+树,更新频繁的字段建立索引会大大降低数据库的性能

(2)区分度不大的属性建立索引,没什么意义,比如班级,假如就三个班或者类似性别这种,区分度就不是很大,不能有效的过滤数据

(3)一般区分度在80%以上的时候就可以建立索引,区分度计算方法:count(distinct(列名))/count(*)

9.创建索引的列,不允许为null,可能会得到不符合预期的结果

10.当需要进行表了解的时候买最好不要超过三张表,因为需要join的字段数据类型必须一致

join是可以走索引的,但是必须保持连接条件数据类型必须一致,否则会失效

11.能使用limit的时候尽量使用limit

不是非要使用哈,加入数据量非常大,你使用limit 100000,10这可不会太快啊,他会有一个类似文件读取时候的指针,要先顺序定位到第100000这条数据,这就会比较慢

大数据量分页可以尝试使用union all或者子查询的方式

12.单表索引建议控制在5个以内

这个貌似是之前的限制,现在没有太多的限制

13.单索引字段数不允许超过5个(组合索引)

14.创建索引的时候应该避免以下错误概念

索引越多越好

过早优化,在不了解系统的情况下进行优化

索引监控

 

10W条数据没有索引_ci_06