索引是一个单独的、存储在磁盘上的数据库结构,它们包含着对数据表里所有记录的引用指针。使用索引用于快速找出在某个或多个列中有一特定值的行,所有MySQL列类型都可以被索引,对相关列使用索引是提高查询操作速度的最佳途径。
优缺点
优点:索引大大提高了查询速度
缺点:占用空间,降低更新表的速度,如对表进行INSERT、UPDATE和DELETE。
索引类型
基于InnoDB存储引擎的索引类型包括单列索引和组合索引,基于MyISAM
单列索引
单列索引即一个索引只包含单个列,单列索引包括普通索引、唯一索引、主键索引
Key(普通索引):是MySQL中的基本索引类型,允许在定义索引的列中插入重复值和空值
Unique(唯一索引):索引列的值必须唯一,但允许有空值。
Primary Key(主键索引):也称为聚集索引,主键索引是一种特殊的唯一索引,不允许有空值。
组合索引
组合索引指在表的多个字段组合上创建的索引,使用组合索引时遵循最左前缀集合
全文索引
全文索引类型为FULLTEXT,在定义索引的列上支持值的全文查找,允许在这些索引列中插入重复值和空值。全文索引可以在CHAR、VARCHAR或者TEXT类型的列上创建
空间索引
空间索引(SPATIAL)是对空间数据类型的字段建立的索引,MySQL中的空间数据类型有4种,分别是GEOMETRY、POINT、LINESTRING和POLYGON。MySQL使用SPATIAL关键字进行扩展,使得能够用于创建正规索引类似的语法创建空间索引。创建空间索引的列必须声明为NOT NULL
最左前缀匹配原则
1 | 查询条件中,MySQL会一直向右匹配直到遇到范围查询(>、<、between、like)就停止匹配,比如a = 1 and b = 2 and c > 3 and d = 4 如果建立(a,b,c,d)顺序的索引,d是用不到索引的,如果建立(a,b,d,c)的索引则都可以用到,a,b,d的顺序可以任意调整。 |
尽量选择区分度高的列作为索引
1 | 区分度就是字段不重复的比例,区分度越高,扫描的记录数越少,唯一键的区分度是1,优先选择唯一性索引可以更快速地确定某条记录。而一些状态、性别字段可能区分度很低。如果非要使用重复值较多的列作为查询条件,可以考虑联合其他列做组合索引,区分度高的列放在前面。也可以选择拆分表。 |
为经常查询的条件建立索引
1 | 比如查询语句经常需要使用`WHERE`,`ORDER BY`,`GROUP BY`,`JOIN ON`等操作,为它们查询的条件建立索引是非常有效的一种优化手段。 |
如果字段很长,可以考虑建立前缀索引
1 | 前缀索引的目的主要是减少字符串作为索引占用的空间,提高查询速度,组合索引中也可以使用前缀索引。 |
限制索引的数目
1 | 索引的数目并不是越多越好,当我们为一个表创建了过多的索引,可能会存在以下几个常见的问题: |
定期删除不需要的索引
1 | 数据的使用方式被改变后,原有的一些索引可能不在需要,应该定期找出这些索引,并将它们删除,从而减少索引对更新操作的影响。 |
少在更新频繁的字段上创建索引
1 | 维护索引是需要一定成本的,在修改表时,对索引的重构和更新很麻烦,如果我们为修改表的某个字段过于频繁建立了索引,这意味着会频繁的更新索引信息,导致较多的IOPS的递增。 |
在业务不繁忙期间添加索引
1 | 不仅仅用在建立索引,凡是对生产表做修改操作时,都应该尽量选择在低峰期做维护操作,这样尽管做了不当操作导致数据库宕机,也可以将成本降到最低。 |
获取查询信息
Explain是MySQL中的一个关键词,用于获取有关查询执行计划的信息。通过在SQL语句前面加上EXPLAIN关键词,MySQL会解释并展示关于如何执行查询的详细信息,包括执行顺序、使用的索引、表的连接类型等。。这对于优化查询性能非常有用。
使用EXPLAIN的语法如下:
1 | EXPLAIN SELECT * FROM table_name WHERE condition; |
输出的列包括:
通过查看EXPLAIN的输出信息,可以识别查询中的性能问题,并进行优化,例如添加合适的索引、重构查询语句等。
查看索引
1 | # 如果查看索引前,没有使用user db_name等命令指定具体的数据库,则必须加上FROM db_name |
创建索引
索引可以在创建表的时候一同创建,也可以在创建表之后在创建索引
创建表的时候创建索引
1 | # 创建普通索引 |
创建表之后创建索引
1 | # 使用`create`关键字创建索引 |
修改索引名称
1 | ALTER TABLE 数据表名 RENAME [INDEX|KEY] 旧索引名 TO 新索引名; |
删除索引
添加AUTO_INCREMENT
约束字段的唯一索引不能被删除
1 | # 使用`drop`关键字删除索引 |
没有查询条件或查询条件没有做索引
1 | 如果sql语句没有添加查询条件,就会进行全表扫描。数据量比较大的表不应该存在全表扫描这种需求的,应该尽量避免全表扫描 |
查询结果集占原表比例较大
1 | 查询的结果集,超过了总行数的15%-30%时,优化器觉得就没有必要走索引了,这个百分比跟数据库的预读能力及其相关参数设置有关 |
索引失效
1 | 索引有自我维护的能力,对于表内容变化比较频繁的情况下,有可能会出现统计信息不准确(数据过旧),从而导致索引失效。通常的解决方案就是删除该索引后重建索引即可解决。 |
查询条件中使用了运算
1 | 查询条件中使用了算术运算或函数运算,比如`SELECT * FROM oldboyedu.student WHERE id-1=9998;`,不会使用索引 |
查询语句使用了隐式转换
1 | 开发经常犯的错误,比如test表中的mobile_number字段是char类型,并且为此字段建立了索引,当使用查询语句`SELECT * FROM test WHERE mobile_number='110';`时,会正常使用索引。 |
模糊查询不走索引
1 | 当查询语句使用了like关键字,结合`%`进行模糊查询,这种情况是不走索引的 |
其他特殊查询条件
1 | !=, >, <, not in 这些条件也可能不使用索引 |
mysqlslap是官方提供的压力测试工具。通过模拟多个并发客户端并发访问MySQL来执行压力测试,同时提供了较详细的SQL执行数据性能报告,并且能很好的对比多个存储引擎(MyISAM,InnoDB等)在相同环境下的相同并发压力下的性能差别。mysqlslap 官方介绍
1 | --host=hostname, -h [hostname] # MySQL服务器的主机名 |
1 | Average number of … |