什么是索引

索引是一种数据结构,提高查询的效率索引会将数据排序,从而能够快速查找数据库除了有数据以外,还维护着一个满足特定查找算法的数据结构,这种数据结构以某种方式指向数据,这样就可以利用这种数据结构高效地查找数据,这种数据结构就是索引。

索引的优点

  1. 提高查询效率,降低IO成本
  2. 对列进行排序,降低排序成本

    索引的缺点

  3. 索引也是一张表,保存了键值对,并指向实际数据,索引列也需要占用空间。

  4. 虽然索引能够提升查询的效率,但是会降低更新的效率,比如insert,update,delete,因为更新表时,mysql不仅要保存新的数据,还要更新索引列的信息。

    索引分类

  5. 单值索引

  6. 唯一索引
  7. 复合索引

    哪些情况可以建索引

  8. 主键自动建立唯一索引

  9. 频繁作为查询条件的字段要建立索引
  10. 与其他表关联的字段,外键字段建立索引
  11. 查询中的排序字段
  12. 查询中统计或分组的字段

    哪些情况不要建索引

  13. 表数据很少(300万一下的)

  14. 经常增删改的字段
  15. 数据重复且平均的字段,这种字段建索引没有意义

    explain

    explain可以模拟优化器执行sql语句,从而可以了解sql语句执行的内部原理,以此来分析性能瓶颈。

    使用方法

    mysql> explain sqlsentence;_

    作用

  16. 表的读取顺序

  17. 数据库读取的操作类型
  18. 哪些索引可以被使用
  19. 哪些索引实际被使用
  20. 表之间的引用
  21. 每张表有多少行被优化器查询

    输出信息

    id

    表的读取顺序

  22. id相同:自上而下执行语句

  23. id不同:id越大,优先级越高,越先执行
  24. id有相同的也有不同的:先执行id最大的第一个,然后平级的顺序执行,再执行小一级id的语句

    select_type

    查询的类型

  25. simple:简单的select查询,查询中不含子查询或union

  26. primary:查询中包含任何复杂的子查询,则最外层的查询是此类型
  27. subquery:查询中包含子查询
  28. derived:临时衍生表
  29. union:第二个select出现在union之后
  30. union result:union之后的结果

    table

    数据对应的表

    type

    显示查询使用了哪种类型

  31. system:表中只有一行数据,是const类型的特例

  32. const:通过索引一次就找到了,通过主键或唯一索引与常量值比较只匹配一行数据,用于单表查询
  33. eq_ref:唯一性索引扫描,对于每个索引键,表中只有一条记录与之匹配,用于多表联查
  34. ref:非唯一索引扫描,返回所有匹配的行
  35. range:检索给定范围的行,比如where中的in、between、>、<
  36. index:只遍历索引树,用于获取表的所有索引字段的数据,select id from table;
  37. all:全表扫描,从磁盘中读取数据,百万级数据查询出现all则需要优化

    possible_key

    显示可能用到的索引值,但不一定会被实际用到

    key

    实际使用到的索引,如果为空则没有使用或者根本没有索引

    key_len

    索引中使用的字节数,长度越短越好它表示索引字段的最大可能长度,而不是实际长度

    ref

    显示那一列索引被用到了,可能是const或者某一列

    rows

    大致估算找到所需信息需要读取的行数

    extra

    额外信息

  38. using filesort:mysql对数据进行重新的排序,无法利用索引进行的排序叫文件排序

  39. using temporary:排序时创建了临时表
  40. using index:查询时不需要回表查询,直接通过索引就可以获取查询的数据,如果出现了using where表示索引列被用来查找特定行,如果没出现则说明索引列只用来提取数据

    索引优化

    防止索引失效

  41. 最佳左前缀法则:如果索引了多个列,查询需要从索引的最前列开始,且不能跳过索引中的列

  42. 不要在索引列上做任何操作,比如各种函数操作,不然会导致索引失效并转向全表扫描
  43. 在where中使用了范围,则范围右边的列失效
  44. 尽量使用覆盖索引(索引列和查询列顺序一致),少用select *
  45. 在使用不等于(!=或者<>)时,无法使用索引,使用的是全表扫描
  46. is null和is not null无法使用索引
  47. like以通配符开头的(like ‘%xyz’),索引会失效,变成全表扫描
  48. 隐式类型转换会导致索引失效
  49. 少用or