MySQL系列---索引(下)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/zhuyanlin09/article/details/101213871

索引的使用原则:

索引由于其提供的优越的查询性能,似乎不使用索引就是一个愚蠢的行为了。但是使用索引,是要付出时间和空间的代价的。因此,索引虽好不可贪多。

下面介绍几个索引的使用技巧和原则。

1.写操作比较频繁的列慎重加索引:索引在提高查询速度的同时,也由于需要更新索引而带来了降低插入、删除和更新带索引列的速度的问题。一张数据表的索引越多,在写操作的时候性能下降的越厉害。

2.索引越多占用磁盘空间越大:与没有加索引比较,加索引会更快地使你的磁盘接近使用空间极限。

3.不要为输出列添加索引:为查询条件、分组、连接条件的列加索引,而不是为查询输出结果的列加索引。

例如:

select ip_address from t_user_action_log
where name='LiSi'
group by action
order by create_time;

所以可以考虑增加在 nameactioncreate_time 列上,而不是 ip_address

4.考虑维度优势:维度越高(理论上维度的最大值就是数据行的总数),数据列包含的独一无二的值就越多,索引的使用效果越好。对于维度很低的数据列,索引几乎不会起作用,因此没有必要加索引。例如性别列的值只有男和女,每种查询结果占比大约50%。一般当查询优化处理器发现查询结果超过全表的30%的时候,就会跳过索引,直接进行全表扫描。

5.对短小值加索引:对短小的值加索引,意味着索引所占的空间更小,可以减少I/O活动,同时比较索引的速度也更快。尤其是主键,要尽可能短小。另外,InnoDB使用的是聚集索引(clustered index),也就是把主键和数据行保存在一起。主键之外的其他索引都是二级索引,这些二级索引也保留着一份主键,这样在查询到索引以后,就可以根据主键找到对应的数据行。如果主键太长的话,会造成二级索引占用的空间变大。

6.为字符串前缀添加索引:前边已经讲过短小索引的种种好处了,有时候一个字符串的前几个字符就能唯一标识这条记录,这个时候设置索引的长度就是非常划算的做法。

7.覆盖索引:如果索引包含满足查询的所有数据,就被称为覆盖索引(Covering Indexes),覆盖索引非常强大,可以大大提高查询性能。

覆盖索引高性能的原因是:

  • 索引通常比记录要小,覆盖索引查询只需要读索引,而不需要读记录。
  • 索引都按照值的大小进行顺序存储,相比与随机访问记录,需要更少的I/0。
  • 大多数数据引擎能更好的缓存索引,例如MyISAM只缓存索引。

8.聚簇索引:聚簇索引(Clustered Indexes)保证关键字的值相近的元组存储的物理位置也相同,且一个表只能有一个聚簇索引。字符串类型不建议使用聚簇索引,特别是随机字符串,因为它们会使系统进行大量的移动操作。并不是所有的存储引擎都支持聚簇索引,目前InnoDB支持。如果使用聚簇索引,最好使用AUTO_INCREMENT列作为主键,应该尽量避免使用随机的聚簇主键。

查询优化建议

前面已经演示过如何使用explain命令分析查询语句了,这里再解释一下其中几个有参考价值的字段的含义:

1.select_type表示查询中每个select子句的类型,一般有下面几个值:

  • SIMPLE 简单SELECT,不使用UNION或子查询等。
  • PRIMARY 查询中若包含任何复杂的子部分,最外层的select被标记为PRIMARY。
  • UNION UNION中的第二个或后面的SELECT语句。
  • DEPENDENT UNION UNION中的第二个或后面的SELECT语句,取决于外面的查询。
  • UNION RESULT UNION的结果。
  • SUBQUERY 子查询中的第一个SELECT。
  • DEPENDENT SUBQUERY 子查询中的第一个SELECT,取决于外面的查询。
  • DERIVED 派生表的SELECT, FROM子句的子查询。
  • UNCACHEABLE SUBQUERY 一个子查询的结果不能被缓存,必须重新评估外链接的第一行。

2.type 表示MySQL在表中找到所需行的方式,又称“访问类型”,常用的类型有:

从左到右,性能从差到好。

  • ALL: Full Table Scan,MySQL将遍历全表以找到匹配的行。
  • index: Full Index Scan,index与ALL区别为index类型只遍历索引树。
  • range: 只检索给定范围的行,使用一个索引来选择行。
  • ref: 表示上述表的连接匹配条件,即哪些列或常量被用于查找索引列上的值。
  • eq_ref: 类似ref,区别就在使用的索引是唯一索引,对于每个索引键值,表中只有一条记录匹配,简单来说,就是多表连接中使用primary key或者 unique key作为关联条件。
  • const: 当MySQL对查询某部分进行优化,并转换为一个常量时,使用这些类型访问。 如将主键置于where列表中,MySQL就能将该查询转换为一个常量。

  • NULL: MySQL在优化过程中分解语句,执行时甚至不用访问表或索引,例如从一个索引列里选取最小值可以通过单独索引查找完成。

3.Key 列显示MySQL实际决定使用的键(索引),如果没有选择索引,键是NULL。

4.possible_keys 指出MySQL能使用哪个索引在表中找到记录,查询涉及到的字段上如果存在索引则该索引将被列出,但不一定被查询使用。

5.ref 表示上述表的连接匹配条件,即哪些列或常量被用于查找索引列上的值。

6.rows 表示MySQL根据表统计信息,以及索引选用的情况,找到所需记录需要读取的行数。这个行数是估算的值,实际行数可能不同。7.Extra 中的很多额外的信息会在 extra 字段显示, 常见的有以下几种内容:

  • using filesort :表示 mysql 需额外的排序操作,不能通过索引顺序达到排序效果。一般有 using filesort都建议优化去掉,因为这样的查询 cpu 资源消耗大。
  • using index:覆盖索引扫描,表示查询在索引树中就可查找所需数据,不用扫描表数据文件,往往说明性能不错。
  • using temporary:查询有使用临时表, 一般出现于排序, 分组和多表 join 的情况, 查询效率不高,建议优化。
  • using where :表名使用了where过滤。

猜你喜欢

转载自blog.csdn.net/zhuyanlin09/article/details/101213871
今日推荐