Mysql

关注公众号 jb51net

关闭
首页 > 数据库 > Mysql > MySQL高性能索引

MySQL创建高性能索引的全步骤

作者:A.iguodala

这篇文章主要给大家介绍了关于MySQL创建高性能索引的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

一、索引基础

1. 索引的类型

1.1 B-Tree 索引

大多数MySQL存储引擎默认使用的是B+树的索引,不同的存储引擎用不同的方式使用B+树索引,MyISAM使用前缀压缩技术使得索引更小,但是InnoDB则按照元数据格式进行存储;MyISAM索引通过数据的物理位置引用被索引的行,而InnoDB则根据主键引用被索引的行。

B树 和 B+ 树

B树:

B+树:

区别:

为什么说 B+树比 B-树更适合实际应用中操作系统的文件索引和数据库索引?

为什么不用红黑树?

1.2 哈希索引

哈希索引基于哈希表实现,对于每一行数据,存储引擎会对所有的索引列计算一个哈希码,通过哈希码能以 O(1) 时间进行查找,但是无法用于排序与分组,并且只支持精确查找,无法用于部分查找和范围查找。

在MySQL 中,只有Memory引擎显式支持哈希索引

InnoDB 存储引擎有一个特殊的功能叫“自适应哈希索引”,当某个索引值被使用的非常频繁时,会在 B+Tree 索引之上再创建一个哈希索引,这样就让 B+Tree 索引具有哈希索引的一些优点,比如快速的哈希查找。

1.3 空间数据索引(R-Tree)

MyISAM 存储引擎支持空间数据索引(R-Tree),可以用于地理数据存储。空间数据索引会从所有维度来索引数据,可以有效地使用任意维度来进行组合查询。

必须使用 GIS 相关的函数来维护数据。

1.4 全文索引

MyISAM 存储引擎支持全文索引,用于查找文本中的关键词,而不是直接比较是否相等。

查找条件使用 MATCH AGAINST,而不是普通的 WHERE。全文索引使用倒排索引实现,它记录着关键词到其所在文档的映射。

InnoDB 存储引擎在 MySQL 5.6.4 版本中也开始支持全文索引。

二、索引的优缺点

优点

缺点

三、高性能索引策略

1. 独立的列

如果MySQL查询的列不是独立的,就不会使用索引,“独立的列”指的是,索引列不能是表达式的一部分,也不能是函数的参数

例如

mysql> SELECT id, name FROM t_user WHERE id + 1 = 5;

MySQL无法解析这个 id + 1 方程式,我们应该养成简化WHERE条件的习惯

2. 前缀索引

有时候需要索引很长的字符列,这会让索引变得大且慢

比如对于 BLOB、TEXT 和 VARCHAR 类型的列,必须使用前缀索引,只索引开始的部分字符。

前缀长度的选取需要根据索引选择性来确定

3. 多列索引

很多人对于多列索引的理解都不够,一个常见的错误就是,为每个列创建独立的索引,或者按照错误的顺序创建多列索引

在多个列上建立独立的单列索引大部分情况下并不能提高MySQL的查询性能,所以引入“索引合并”的策略,一定程度上可以使用表上的多个单列索引来定位指定的行。

例如下面的语句中,最好把 username 和 password 设置为多列索引。

SELECT username, password FROM t_user WHERE username = 'Aiguodala' AND password = 'Aiguodala';

4. 合适的索引列顺序

让选择性最强的索引列放在前面。

索引的选择性是指:不重复的索引值和记录总数的比值。最大值为 1,此时每个记录都有唯一的索引与其对应。选择性越高,每个记录的区分度越高,查询效率也越高。

5. 聚簇索引

聚簇索引并不是一种单独的索引类型,而是一种数据存储方式,术语“聚簇”表示数据行和相邻的键值紧凑地存储在一起。

InnoDB 通过主键聚集数据,如果没有定义主键,InnoDB会选择一个唯一的非空索引来代替,如果没有这样的索引,InnoDB会隐式的定义一个主键来作为聚簇索引。

聚集的数据的优缺点

优点:

缺点:

非聚簇索引

将数据存储于索引分开结构,索引结构的叶子节点指向了数据的对应行,myisam通过key_buffer把索引先缓存到内存中,当需要访问数据时(通过索引访问数据),在内存中直接搜索索引,然后通过索引找到磁盘相应数据,这也就是为什么索引不在key buffer命中时,速度慢的原因

6. 覆盖索引

索引覆盖所有需要查询的字段的值

好处:

三、查询性能优化

1. Explain 性能分析

使用 EXPLAIN 关键字可以模拟优化器执行 SQL 查询语句,从而知道 MySQL 是如何处理你的 SQL 语句的。分析你的查询语句或是表结构的性能瓶颈

举例:

1.1 id:表的读取顺序

id是select查询的序列号,包含一组数字,表示查询中执行select子句或操作表的顺序

id相同:执行顺序为 从上至下执行

EXPLAIN SELECT * FROM t1, t2, t3 WHERE t1.id = t2.id AND t2.id = t3.id;

id不同:执行顺序为 id大的先执行

EXPLAIN SELECT t2.id FROM t2 WHERE t2.id = 
(SELECT t1.id FROM t1 WHERE t1.id = 
(SELECT t3.id FROM t3)
);

1.2 select_type:查询操作类型

select_type代表查询的类型,主要是用于区别普通查询、联合查询、子查询等的复杂查询

select_type 属性 含义
SIMPLE 简单的 select 查询,查询中不包含子查询或者 UNION
PRIMARY 查询中若包含任何复杂的子部分,最外层查询则被标记为 Primary
DERIVED 在 FROM 列表中包含的子查询被标记为 DERIVED(衍生) MySQL 会递归执行这些子查询, 把结果放在临时表里
SUBQUERY 在SELECT或WHERE列表中包含了子查询,WHERE 后面是单个值(=)
DEPEDENT SUBQUERY 在SELECT或WHERE列表中包含了子查询,子查询基于外层,WHERE 后面是一组值(IN)
UNCACHEABLE SUBQUERY 无法使用缓存的子查询
UNION 若第二个SELECT出现在UNION之后,则被标记为UNION; 若UNION包含在FROM子句的子查询中,外层SELECT将被标记为:DERIVED
UNION RESULT 从UNION表获取结果的SELECT

1.3 table:表的来源

table表示这个数据是基于哪张表的

1.4 type:访问类型

type 是查询的访问类型。是较为重要的一个指标,结果值从最好到最坏依次是:

system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > all

--常见的顺序为
system > const > eq_ref > ref > range > index > all

一般来说,得保证查询至少达到 range 级别,最好能达到 ref

类型名 含义
SYSTEM 表只有一行记录(等于系统表),这是 const 类型的特列,平时不会出现,这个也可以忽略不计
CONST 表示通过索引一次就找到了,const 用于比较 primary key 或者 unique 索引。因为只匹配一行数据,所以很快。如将主键置于 where 列表中,MySQL 就能将该查询转换为一个常量
EQ_REF 唯一性索引扫描,对于每个索引键,表中只有一条记录与之匹配。常见于主键或唯一索引扫描
REF 非唯一性索引扫描,返回匹配某个单独值的所有行。本质上也是一种索引访问,它返回所有匹配某个单独值的行, 然而,它可能会找到多个符合条件的行,所以他应该属于查找和扫描的混合体
RANGE 只检索给定范围的行,使用一个索引来选择行。key 列显示使用了哪个索引一般就是在你的 where 语句中出现 了 between、<、>、in 等的查询这种范围扫描索引扫描比全表扫描要好,因为它只需要开始于索引的某一点,而 结束语另一点,不用扫描全部索引
INDEX 出现index是sql使用了索引但是没用通过索引进行过滤,一般是使用了覆盖索引或者是利用索引进行了排序分组
ALL Full Table Scan,将遍历全表以找到匹配的行

1.5 possible_key:可能用到的索引

显示可能应用在这张表中的索引,一个或多个。查询涉及到的字段上若存在索引,则该索引将被列出,但不一 定被查询实际使用

1.6 key:实际使用的索引

实际使用的索引。如果为NULL,则没有使用索引

1.7 key_len:索引使用字节数

表示索引中使用的字节数,可通过该列计算查询中使用的索引的长度。 key_len 字段能够帮你检查是否充分的利用上了索引

ken_len 越长,说明索引使用的越充分

1.8 ref:显示被使用的索引的具体信息

ref显示索引的哪一列被使用了,如果可能的话,可以是一个常数。哪些列或常量被用于查找索引列上的值

1.9 rows:被查询的行数

rows 列显示 MySQL 认为它执行查询时必须检查的行数。越少越好!

1.10 Extra:额外重要信息

其他的额外重要的信息

总结

到此这篇关于MySQL创建高性能索引的文章就介绍到这了,更多相关MySQL高性能索引内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文