MySQL索引详细解析

目录
  • 1. MySQL 索引的最左前缀原则
  • 2. 前缀索引
  • 3. 索引下推(ICP——Index Condition Pushdown)
  • 4. 查看 MySQL 语句是否用到索引
  • 5. 为什么官方建议用自增长主键作为索引
  • 6. 如何创建索引
  • 7. 创建索引注意事项
  • 8. 使用索引一定可以提高查询性能嘛
  • 9. 索引失效

1. MySQL 索引的最左前缀原则

左前缀原则是联合索引在使用时要遵循的原则,查询索引可以使用联合索引的一部分,但是必须从最左侧开始。在创建联合索引时,要根据业务需求,where子句中将使用最频繁的一列放在最左边,mysql会一直向右匹配直到遇到范围查询(>、<、between、like)时停止匹配。即范围列可以用到索引,范围列后面的列无法用到索引。

比如查询 a = 1 and b = 2 and c > 3 and d = 4 如果建立 (a,b,d,c) 顺序的索引,d是用不到索引的,如果建立 (a,b,d,c) 的索引则都可以用到,a,b,d的顺序可以任意调整。可以调整 a,b,c 顺序的原因是 MySQL 具有查询优化器

MySQL 查询优化器

当按照索引中所有列进行精确匹配(“=” 或 “IN”)时,索引可以被用到,并且 type 为 const。理论上索引对顺序是敏感的,但是 MySQL 的查询优化器会自动调整 where 子句的条件顺序以使用适合的索引,所以 MySQL 在进行精确匹配时不存在因 where 子句的顺序问题而造成索引失效。

2. 前缀索引

定义: 对于BLOB、TEXT,或者很长的VARCHAR类型的列,为它们的前几个字符(具体几个字符是在建立索引时指定的)建立索引,这样的索引就叫前缀索引。

优点: 这样建立起来的索引更小,所以查询更快。

缺点: 不能在 ORDER BY 或 GROUP BY 中使用前缀索引,也不能把前缀索引用作覆盖索引。

创建方法:

alter table table_name add key( column_name( prefix_length));

注:这里最关键的参数就是 prefix_length,这个值需要根据实际表的内容,来得到合适的索引选择性。

prefix_length 计算方法:

先计算完整列的选择性 :

select count(distinct col_1)/count(1) from table_1

再计算不同前缀长度的选择性 :

select count(distinct left(col_1,4))/count(1) from table_1

到最优长度之后,创建前缀索引 :

create index idx_front on table_1 (col_1(4))

3. 索引下推(ICP——Index Condition Pushdown)

定义: 索引下推 Index Condition Pushdown(ICP) 是MySQL使用索引从表中检索行数据的一种优化方式,从 MySQL5.6 开始支持。5.6 之前,存储引擎会通过遍历索引定位基表中的行,然后返回给 Server层,再去为这些数据行进行 WHERE 后的条件的过滤。MySQL5.6之后支持 ICP,如果WHERE条件可以使用索引,MySQL 会把这部分过滤操作放到存储引擎层,存储引擎通过索引过滤,把满足的行从表中读取出。ICP 能减少引擎层访问基表的次数(回表次数)和 Server层访问存储引擎的次数。

MySQL通过 optimizer_switch 参数中的 index_condition_pushdown 选项来控制,默认是开启的。

操作:

查看是否开启

show variables like'% optimizer_switch%';

设置 ICP

SET optimizer_switch = ‘index_condition_pushdown=off';

例子:

在 people_table中有一个二级索引(zipcode,lastname,firstname),查询是

SELECT * FROM people WHERE zipcode='95054′ AND lastname LIKE ‘%etrunia%' AND address LIKE ‘%Main Street%';
  • 如果没有使用索引下推技术,则MySQL会通过zipcode=’95054’从存储引擎中查询对应的数据,返回到MySQL服务端,然后MySQL服务端基于lastname LIKE ‘%etrunia%’ and address LIKE ‘%Main Street%’来判断数据是否符合条件
  • 如果使用了索引下推技术,则MYSQL首先会返回符合zipcode=’95054’的索引,然后根据lastname LIKE ‘%etrunia%’ and address LIKE ‘%Main Street%’来判断索引是否符合条件。如果符合条件,则根据该索引来定位对应的数据,如果不符合,则直接reject掉。

4. 查看 MySQL 语句是否用到索引

1. 方法一:通过 show index 查看表中含那些索引

show index from table_name

2. 方法二:通过 explain 命令查看 SQL 语句的执行计划:

例子:

explain select * from t where name = 'name1';

  • 我们可以先从查询类型type列开始查看,如果出现all关键字,后面的内容就都可以不用看了,代表全表扫描。—— const(主键索引或者唯一二级索引进行等值匹配的情况下),ref(普通的⼆级索引列与常量进⾏等值匹配),index(扫描全表索引的覆盖索引)
  • 再看key列,看是否使用了索引, null代表没有使用索引。
  • 然后看rows列,该列用来表示在SQL执行过程中被扫描的行数,该数值越大,意味着需要扫描的行数越多,相应的耗时就更长。
  • 最后再看extra列,在这列中要观察是否有Using filesort或者Using temporary这样的关键字出现,这些是很影响数据库性能的。
  • MySQL5.7的执行计划中会默认添加filtered列 (MySQL5.6 使用 explain extended 也会增加此列),它指返回结果的行占需要读到的行(rows 列的值)的百分比。需要注意的是, explain中输出的rows只是一个估算值。本例中该表进行了全表扫描。

5. 为什么官方建议用自增长主键作为索引

减少分裂和移动的频率: 结合B+Tree的特点,自增主键是连续的,在插入过程中能尽量减少页分裂,即使要进行页分裂,也只会分裂很少一部分。并且能减少数据的移动,每次插入都是插入到最后。

6. 如何创建索引

1. 在执行 CREATE TABLE 时创建索引

CREATE TABLE user_index2 (
 id INT auto_increment PRIMARY KEY,
 first_name VARCHAR (16),
 last_name VARCHAR (16),
 id_card VARCHAR (18),
 information text,
 KEY name (first_name, last_name),
 FULLTEXT KEY (information),
 UNIQUE KEY (id_card)
);

2. 使用ALTER TABLE命令去增加索引

ALTER TABLE table_name ADD INDEX index_name (column_list);

ALTER TABLE 可用来创建普通索引、UNIQUE索引或PRIMARY KEY索引。

其中 table_name 是要增加索引的表名,column_list 指出对哪些列进行索引,多列时各列之间用逗号分隔。

索引名 index_name 可自己命名,缺省时,MySQL将根据第一个索引列赋一个名称。另外,ALTER TABLE允许在单个语句中更改多个表,因此可以在同时创建多个索引。

3. 使用CREATE INDEX命令创建。

CREATE INDEX index_name ON table_name (column_list);

7. 创建索引注意事项

  • 选择性低的字段不要创建索引(例如,性别sex、状态status)。
  • 很少查询的列不要创建索引(项目初期就要确定好)。
  • 大数据类型字段不要创建索引。
  • 尽量避免不要使用NULL,应该指定列为NOTNULL(在MySQL中,含有空值的列很难进行查询优化,它们会使得索引、索引的统计信息及比较运算更加复杂。可以使用空字符串代替空值)。

8. 使用索引一定可以提高查询性能嘛

通常通过索引查询数据比全表扫描要快。但是我们也必须注意到它的代价。索引需要空间来存储,也需要定期维护, 每当有记录在表中增减或索引列被修改时,索引本身也会被修改。 这意味着每条记录的I* NSERT,DELETE,UPDATE将为此多付出4,5 次的磁盘I/O。 因为索引需要额外的存储空间和处理,那些不必要的索引反而会使查询反应时间变慢。使用索引查询不一定能提高查询性能。

9. 索引失效

  • 通过索引扫描的行记录数超过全表的30%,优化器就不会走索引,而变成全表扫描。
  • 联合索引中,第一个查询条件不是最左索引列。 —— 优化器
  • 联合索引中,第一个查询条件不是最左前缀列。—— 优化器
  • 联合索引中,第一个索引列使用范围查询,只能使用到部分索引,有ICP出现 (范围查询是指<、=、<=、BETWEEN and)。
  • 模糊查询条件列最左以通配符%开始(可以考虑放到子查询里面)。
  • 两个单列索引,一个用于检索,一个用于排序。这种情况下只能使用到一个索引。因为查询语句中最多只能使用一个索引,考虑建立联合索引。
  • 查询字段上面有索引,但是使用了函数运算。

到此这篇关于MySQL索引详细解析的文章就介绍到这了,更多相关MySQL索引内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 一文搞懂什么是MySQL前缀索引

    目录 一.什么是前缀索引 二.为什么要用前缀索引 三.怎么创建前缀索引 四.使用前缀索引需要注意的事项 五.小结 一.什么是前缀索引 所谓前缀索引,说白了就是对文本的前几个字符建立索引(具体是几个字符在建立索引时去指定),比如以产品名称的前 10 位来建索引,这样建立起来的索引更小,查询效率更快! 有点类似于 Oracle 中对字段使用 Left 函数来建立函数索引,只不过 MySQL 的这个前缀索引在查询时是内部自动完成匹配的,并不需要使用 Left 函数. 二.为什么要用前缀索引 可能有的同

  • 详解MySQL单列索引和联合索引

    目录 一.简介 二.单列索引 三.最左前缀原则 四.同时存在联合索引和单列索引(字段有重复) 五.联合索引本质 六.索引失效 七.其它知识点 八.MySQL存储引擎简介 九.索引结构(方法.算法) 一.简介 利用索引中的附加列,可以缩小搜索的范围,但使用一个具有两列的索引不同于使用两个单独的索引. 联合索引的结构与电话簿类似,人名由姓和名构成,电话簿首先按姓氏进行排序,然后按名字对有相同姓氏的人进行排序.如果您知道姓,电话簿将非常有用,如果您知道姓和名,电话簿则更为有用,但如果您只知道名不知道姓

  • MySql索引原理与操作

    目录 1. 什么是索引 2. 索引的实现原理 3. 添加索引的条件 4. 索引的操作 1. 创建索引 2. 删除索引 3. 查看一个sql语句是否使用了索引进行检索 5. 索引的失效 6. 索引的类型 1. 什么是索引 索引是在数据库表的字段上添加的,是为了提高查询效率存在的一种机制. 一张表的一个字段可以添加一个索引,当然,多个字段联合起来也可以添加索引. 索引相当于一本书的目录,是为了缩小扫描范围而存在的一种机制. 索引相当于一本书的目录 通过索引查询的方式被称为索引查询. 在 mysql

  • MySQL索引介绍及优化方式

    目录 一.导致sql执行慢的原因 二.分析原因时,一定要找切入点 三.什么是索引? 四.Explain分析 1.id 2.select_type 3.table 4.type(★) 5.possible_key 6.key(★) 7.key_len 8.ref(★) 9.rows(★) 10.extra 五.优化案例 六.是否需要创建索引? 一.导致sql执行慢的原因 硬件条件限制: io吞吐量小,形成瓶颈(读取磁盘数据) 网络传输速度慢 内存不足(读取磁盘数据加载到内存) 程序设计方面: 没有

  • MySQL 中这么多索引该怎么选择

    目录 前言 MySQL 单字段索引问题 组合索引 唯一索引和普通索引 总结 前言 索引的本质是存储引擎用于快速查询记录的一种数据结构.特别是数据表中数据特别多的时候,索引对于数据库的性能就愈发重要. 在数据量比较大的时候,不恰当的索引对于数据库的性能的影响是非常大的.在实际的应用中常常会遇见使用错误的索引而导致一系列问题,所以,选择正确的索引对于 MySQL 数据库来说相当重要. 下面我们就来一起聊聊在 MySQL 数据库中该怎么选择正确的索引. 在了解怎么选择索引之前,我先给你举一个例子.如果

  • MySQL中索引的定义以及操作新手教程

    目录 索引的定义 索引的类型 普通.唯一.主键和全文索引 普通索引(INDEX) 唯一索引(UNIQUE INDEX) 主键索引(PRIMARY KEY) 全文索引(FULLTEXT) 单列索引和组合索引 聚集索引和非聚集索引 索引的创建原则 索引操作 创建索引 查看索引 删除索引 总结 索引的定义 数据库中的索引就像一本书的目录,可以据此快速定位数据库中相关数据的所在位置. 在数据库中,索引被定义为一种特殊的数据结构,由数据库中的一列或多列组合而成,可以用来快速查询数据表中某一特定值的记录.

  • MySQL索引详细解析

    目录 1. MySQL 索引的最左前缀原则 2. 前缀索引 3. 索引下推(ICP——Index Condition Pushdown) 4. 查看 MySQL 语句是否用到索引 5. 为什么官方建议用自增长主键作为索引 6. 如何创建索引 7. 创建索引注意事项 8. 使用索引一定可以提高查询性能嘛 9. 索引失效 1. MySQL 索引的最左前缀原则 左前缀原则是联合索引在使用时要遵循的原则,查询索引可以使用联合索引的一部分,但是必须从最左侧开始.在创建联合索引时,要根据业务需求,where

  • MySql索引详细介绍及正确使用方法

    MySql索引详细介绍及正确使用方法 1.前言: 索引对查询的速度有着至关重要的影响,理解索引也是进行数据库性能调优的起点. 索引是存储引擎用于快速查找记录的一种数据结构,通过合理的使用数据库索引可以大大提高系统的访问性能,接下来主要介绍在MySql数据库中索引类型,以及如何创建出更加合理且高效的索引技巧. 注:这里主要针对的是InnoDB存储引擎的B+Tree索引数据结构 2.索引的优点 1.大大减轻了服务器需要扫描的数据量,从而提高了数据的检索速度 2.帮助服务器避免排序和临时表 3.可以将

  • Mysql索引详细介绍

    Mysql索引概述 所有MySQL列类型可以被索引.对相关列使用索引是提高SELECT操作性能的最佳途径.根据存储引擎定义每个表的最大索引数和最大索引长度.所有存储引擎支持每个表至少16个索引,总索引长度至少为256字节.大多数存储引擎有更高的限制. 在MySQL 5.1中,对于MyISAM和InnoDB表,前缀可以达到1000字节长.请注意前缀的限制应以字节为单位进行测量,而CREATE TABLE语句中的前缀长度解释为字符数.当为使用多字节字符集的列指定前缀长度时一定要加以考虑. 还可以创建

  • mysql 索引详细介绍

    mysql 索引详解: 在mysql 中,索引可以分为两种类型 hash索引和 btree索引. 什么情况下可以用到B树索引?  1.全值匹配索引 比如: orderID="123" 2.匹配最左前缀索引查询  比如:在userid 和 date字段上创建联合索引. 那么如果输入 userId作为条件,那么这个userid可以使用到索引,如果直接输入 date作为条件,那么将不能使用到索引. 3.匹配列前缀查询 比如: order_sn like '134%' 这样可以使用到索引. 4

  • MySQL索引结构详细解析

    目录 简介 索引结构(树) 为什么用树,而不用哈希表 BTree索引 B+Tree索引 聚簇索引与非聚簇索引 索引分类 性能分析 索引创建场景 简介 在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构上实现高级查找算法.这种数据结构,就是索引. 一般来说索引本身也很大,不可能全部存储在内存中,因此索引往往以索引文件的形式存储的磁盘上. 优点: 1.类似大学图书馆建书目索引,提高数据检索的效率,降低数据库的IO成本. 2.通过

  • MySQL索引事务详细解析

    目录 一.索引 1.概念 2.作用 3.缺陷 4.使用场景 5.使用 1.查看索引 2.创建索引 3.删除索引 6.案例 二.事务 1.为什么使用事务 2.事务的概念 3.使用 4.特性 一.索引 1.概念 索引是一种特殊的文件,包含着对数据表里所有记录的引用指针,可以对表中的一列或者多列创建索引,并指定索引的类型,各类索引有各自的数据结构实现. (这里对于索引也只是简单了解,写了些皮毛) 更浅显易懂的来说:数据库的数据保存在硬盘,硬盘不知道具体保存在哪个位置,索引就是用来告诉硬盘数据在哪个位置

  • MySQL索引机制的详细解析及原理

    目录 一.索引的类型与常见的操作 二.常见的索引详解与创建 三.索引的原理 1.通过实验介绍B+tree 2.延伸 四.聚簇索引和非聚簇索引 1.使用聚簇索引的优势 2.什么情况下无法使用索引 总结 一.索引的类型与常见的操作 前缀索引 MySQL 前缀索引能有效减小索引文件的大小,提高索引的速度.但是前缀索引也有它的坏处:MySQL 不能在 ORDER BY 或 GROUP BY 中使用前缀索引,也不能把它们用作覆盖索引(Covering Index). 复合索引 集一个索引包含多个列(最左前

  • Mysql中复制详细解析

    1.mysql复制概念 指将主数据库的DDL和DML操作通过二进制日志传到复制服务器上,然后在复制服务器上将这些日志文件重新执行,从而使复制服务器和主服务器的数据保持同步.复制过程中一个服务器充当主服务器(master),而一个或多个其它服务器充当从服务器(slaves).主服务器将更新重新写入二进制日志文件,并维护文件的一个索引以跟踪日志循环.这些日志可以记录发送到从服务器的更新.当一个从服务器连接主服务器时,它通知主服务器.从服务器在日志中读取的最后一次成功更新的位置.从服务器接受从那时起发

  • 远程数据库的表超过20个索引的影响详细解析

    昨天同事参加了一个研讨会,有提到一个案例.一个通过dblink查询远端数据库,原来查询很快,但是远端数据库增加了一个索引之后,查询一下子变慢了. 经过分析,发现那个通过dblink的查询语句,查询远端数据库的时候,是走索引的,但是远端数据库添加索引之后,如果索引的个数超过20个,就会忽略第一个建立的索引,如果查询语句恰好用到了第一个建立的索引,被忽略之后,只能走Full Table Scan了. 听了这个案例,我查了一下,在oracle官方文档中,关于Managing a Distributed

  • MySQL DELETE语法使用详细解析

    以下的文章主要描述的是MySQL DELETE语法的详细解析,首先我们是从单表语法与多表语法的示例开始的,假如你对MySQL DELETE语法的相关内容十分感兴趣的话,你就可以浏览以下的文章对其有个更好的了解. 单表语法: 复制代码 代码如下: DELETE [LOW_PRIORITY] [QUICK] [IGNORE] FROM tbl_name   [WHERE where_definition]   [ORDER BY ...]   [LIMIT row_count] 多表语法: 复制代码

随机推荐