暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

MYSQL调优-索引(一)

懒人实录 2021-08-31
540

索引的优点

  • 大大减少了服务器需要扫描的数据量

  • 帮助服务器避免排序和临时表

  • 将随机io变成顺序io


索引的用处

  • 快速查找匹配WHERE子句的行

  • 从consideration中消除行,如果可以在多个索引之间进行选择,mysql通常会使用找到最少行的索引

  • 如果表具有多列索引,则优化器可以使用索引的任何最左前缀来查找行

  • 当有表连接的时候,从其他表检索行数据

  • 查找特定索引列的min或max值

  • 如果排序或分组时在可用索引的最左前缀上完成的,则对表进行排序和分组

  • 在某些情况下,可以优化查询以检索值而无需查询数据行


索引的分类

  • 主键索引

          它是一种特殊的唯一索引,不允许有空值。一般是在建表的时候指定了主键,就会创建主键索引, CREATE INDEX不能用来创建主键索引,使用 ALTER TABLE来代替

  • 唯一索引

    与普通索引类似,不同的就是:索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须一。

  • 普通索引

    这是最基本的索引,它没有任何限制。

  • 全文索引

    FULLTEXT索引用于全文搜索。只有InnoDB和 MyISAM存储引擎支持 FULLTEXT索引和仅适用于 CHAR, VARCHAR和 TEXT列。

  • 组合索引

两个或更多个列上的索引被称作复合索引。利用索引中的附加列,您可以缩小搜索的范围。使用方式如下:
1、在where条件中需要加索引的字段
2、数据量少的字段不需要加索引
3、如果where条件中是OR关系,加索引不起作用
4、符合最左原则

创建索引
alter table staffs add index idx_nap(name, age, pos);

看表索引
show index from staffs(表名);


执行计划分析SQL语句执行
1、全匹配
全值匹配指的是和索引中的所有列进行匹配
  • id:一个查询

  • possible_keys:可供选择的索引名称

  • key:实际使用的索引名称

  • ref:显示索引的哪一列被使用到,因为 name = 'July' and age = '23' and pos = 'dev',给的是具体值,所以显示const(常数)

  • rows:大致估算出找出所需记录需要读取的行数,这边显示1执行效率比较高的

  • type:访问类型,效率从最好到最坏依次是:system > const > eq_ref > ref>fulltext>ref_or_null>index_merge>unique_subquery>index_subquery > range > index > ALL

一般情况下,得保证查询至少达到range级别,最好能达到ref
  • key_len:表示索引中使用的字节数,可以通过key_len计算查询中使用的索引长度,在不损失精度的情况下长度越短越好

通过以上方式可以看出这条语句全匹配使用了刚刚创建的索引
2、匹配最左前缀
只匹配前面的几列
查询使用了 name,age的索引进行查询
explain select * from staffs where name = 'July' and age = '23';

  • tyep:ref(使用了非唯一性索引进行数据的查找)

  • ref:cons,const 两个查询条件常量


3、匹配列前缀
可以匹配某一列的值的开头部分
使用name索引,匹配name开头为J的数据
 explain select * from staffs where name like 'J%';

  • type:range(指定范围内进行查询

  • key:索引名称 idx_nap

  • ref:为null,表示不明白使用哪些列 

注意:在前面加%会导致索引失效

explain select * from staffs where name like '%y';

  • type:  ALL(全表扫描)

  • key、ref 都为null

没有使用到索引,查询效率会比较低

4、匹配范围值

查找某一个范围的数据

  • type:range(范围查询)

  • key:idx_nap(索引名称)

  • Extra:Using index condition(使用了索引的一些条件)


5、精确匹配某一列并范围匹配另外一列

可以查询第一列的全部和第二列的部分


使用 name和age进行查询

explain select * from staffs where name = 'July' and age > 25;

  • type:range(范围查询)

  • ref:null


sql查询严格按照索引的顺序name,age,pos。该语句没有age,导致不会使用pos索引,只使用了name的索引,所以,type会是ref,ref是const。

alter table staffs add index idx_nap(name, age, pos);
explain select * from staffs where name = 'July' and pos > 25;



创建索引时pos在age后面,在执行sql语句的时候Mysql会自动调节参数位置,这时ref 会有三个常量

 explain select * from staffs where name = 'July' and pos='dev' and age =20;


6、只访问索引的查询

查询的时候只需要访问索引,不需要访问数据行,本质上就是覆盖索引

Extra出现Using index表示当前查询中有索引覆盖

 explain select name,age,pos from staffs where name = 'July' and age = 25 and pos = 'dev';

文章转载自懒人实录,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论