博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
MySQL - 索引总结
阅读量:3781 次
发布时间:2019-05-22

本文共 5428 字,大约阅读时间需要 18 分钟。

 目录


 

一、索引 - 优化查询

1-0 查询的三种情况

  • 缓存查询(不在mysql中进行数据查询)
  • 全表扫描
  • 索引扫描

1-1 索引种类

  • Btree(btree  b+tree b*tree) - 二叉树
    • BTREE索引就是一种将索引值按一定的算法,存入一个树形的数据结构中(二叉树),每次查询都是从树的入口root开始,依次遍历node,获取leaf。这是MySQL里默认和最常用的索引类型
  • Rtree
    • RTREE在MySQL很少使用,仅支持geometry数据类型,支持该类型的存储引擎只有MyISAM、BDb、InnoDb、NDb、Archive几种。
      相对于BTREE,RTREE的优势在于范围查找
  • HASH
    • 由于HASH的唯一(几乎100%的唯一)及类似键值对的形式,很适合作为索引。
      HASH索引可以一次定位,不需要像树形索引那样逐层查找,因此具有极高的效率。但是,这种高效是有条件的,即只在“=”和“in”条件下高效,对于范围查询、排序及组合索引仍然效率不高。
  • FullText - 全文索引
    • 即为全文索引,目前只有MyISAM引擎支持。其可以在CREATE TABLE ,ALTER TABLE ,CREATE INDEX 使用,不过目前只有 CHAR、VARCHAR ,TEXT 列上可以创建全文索引。
      全文索引并不是和MyISAM一起诞生的,它的出现是为了解决WHERE name LIKE “%word%"这类针对文本的模糊查询效率较低的问题。

二、普通索引 - 单例索引、组合索引

MySQL索引的建立可以大大提高MySQL的检索速度。

索引分单列索引组合索引

单列索引,即一个索引只包含单个列,一个表可以有多个单列索引,但这不是组合索引。

组合索引,即一个索引包含多个列。
创建索引时,你需要确保该索引是应用在 SQL 查询语句的条件(一般作为 WHERE 子句的条件)。

实际上,索引也是一张表,该表保存了主键与索引字段,并指向实体表的记录。

索引的缺点:

  • 虽然索引大大提高了查询速度,同时却会降低更新表的速度,如对表进行INSERT、UPDATE和DELETE。因为更新表时,MySQL不仅要保存数据,还要保存一下索引文件。
  • 建立索引会占用磁盘空间的索引文件。
  • 建立索引的时候,速度很慢

注:一旦表创建索引,所有查询首先查询索引,再根据索引定位的结果去找数据。

2-1 普通索引的创建方式(三种)

2-1-1 创建表是建立索引

CREATE TABLE 表名 (                字段名1  数据类型 [完整性约束条件…],                字段名2  数据类型 [完整性约束条件…],                [UNIQUE | FULLTEXT | SPATIAL ]   INDEX | KEY                [索引名]  (字段名[(长度)]  [ASC |DESC])                 );CREATE TABLE mytable(       ID INT NOT NULL,       username VARCHAR(16) NOT NULL,      INDEX [indexName] (username(length))   );

2-1-2 在已存在的标上创建索引 - CREATE

CREATE  [UNIQUE | FULLTEXT | SPATIAL ]  INDEX  索引名                      ON 表名 (字段名[(长度)]  [ASC |DESC]) ;CREATE INDEX indexName ON mytable(username(length));

2-1-3 在已存在表上创建索引 -  ALTER TABLE

ALTER TABLE 表名 ADD  [UNIQUE | FULLTEXT | SPATIAL ] INDEX                             索引名 (字段名[(长度)]  [ASC |DESC]) ;ALTER table tableName ADD INDEX indexName(columnName)

2-2 普通索引的删除方式

DROP INDEX [indexName] ON mytable;

2-3 查看索引信息

SHOW INDEX FROM table_name; \G

三、基于Btree的索引

 

  • 聚集索引:基于主键,自动生成的,一般是建表时创建主键.如果没有主键,自动选择唯一键做为聚集索引.
  • 辅助索引:人为创建的(普通,覆盖);MUL
  • 唯一索引:人为创建(普通索引,聚集索引);UNI,如果有重复值是创建不了的

聚集索引和辅助索引的对比总结

  • 聚集索引:叶子结点,按照主键列的顺序,存储的整行数据,就是真正的数据页
  • 辅助索引: 叶子结点,列值排序之后,存储到叶子结点+对应的主键的值,便于回表查询

 

3-1 聚集索引

聚集索引(clustered index)就是按照每张表的主键(primary key)构造一棵B+树,同时叶子结点存放的即为整张表的行记录数据,也将聚集索引的叶子结点称为数据页。聚集索引的这个特性决定了索引组织表中数据也是索引的一部分。

特点:叶子节点存放的一整条数据

如果未定义主键,MySQL取第一个唯一索引(unique)而且只含非空列(NOT NULL)作为主键,InnoDB使用它作为聚簇索引。

如果没有这样的列,InnoDB就自己产生一个这样的ID值,它有六个字节,而且是隐藏的,使其作为聚簇索引。
由于实际的数据页只能按照一棵B+树进行排序,因此每张表只能拥有一个聚集索引。在多少情况下,查询优化器倾向于采用聚集索引。因为聚集索引能够在B+树索引的叶子节点上直接找到数据。此外由于定义了数据的逻辑顺序,聚集索引能够特别快地访问针对范围值得查询。
 

3-2 辅助索引

表中除了聚集索引外其他索引都是辅助索引(Secondary Index,也称为非聚集索引)

与聚集索引的区别是:辅助索引的叶子节点不包含行记录的全部数据。

特点:如果是按照这个字段创建的索引,那么叶子节点存放的是:{名字:名字所在那条记录的主键的值}

叶子节点除了包含键值以外,每个叶子节点中的索引行中还包含一个书签(bookmark)。该书签用来告诉InnoDB存储引擎去哪里可以找到与索引相对应的行数据。

3-2-1 覆盖索引 and 非覆盖索引

覆盖索引:只在辅助索引的叶子节点中就已经找到了所有想要的数据

select name from user where name='name1';

非覆盖索引:查找非叶子节点存在的数据

select age from user where name='name1';

3-2-2 普通辅助索引创建 (MUL)

alter table blog_userinfo add key idx_email(email);create index idx_phone on blog_userinfo(phone);

3-2-3 查看索引结构

desc blog_userinfo;show index from blog_userinfo;

3-2-4 删除索引

alter table blog_userinfo drop index idx_email;drop index idx_phone on   blog_userinfo;

3-3 前缀索引

对于列的值较长,比如BLOB、TEXT、VARCHAR,就必须建立前缀索引,即将值的前一部分作为索引。这样既可以节约空间,又可以提高查询效率。但无法使用前缀索引做 ORDER BY 和 GROUP BY,也无法使用前缀索引做覆盖扫描。

语法ALTER TABLE table_name ADD KEY(column_name(prefix_length));示例ALTER TABLE city ADD KEY(cityname(7))select count(*),substring(password,1,20) as sbp  from blog_userinfo group by sbp;alter table blog_userinfo add index idx(password(10));

3-4 唯一键索引

唯一索引,一种索引,不允许具有索引值相同的行,从而禁止重复的索引或键值。系统在创建该索引时检查是否有重复的键值,并在每次使用 INSERT 或 UPDATE 语句添加数据时进行检查。

alter table blog_userinfo add unique key uni_email(email);

3-5 覆盖索引 with 联合索引

作用:不需要回表查询,不需要聚集索引,所有查询的数据都从辅助索引中获取

联合索引:指对表上的多个列合起来做一个索引。联合索引的创建方法与单个索引的创建方法一样,不同之处在仅在于有多个索引列

mysql> create table t(    -> a int,    -> b int,    -> primary key(a),    -> key idx_a_b(a,b)    -> );Query OK, 0 rows affected (0.11 sec)alter table t1 add index idx_gam(gender,age,money);

覆盖索引:InnoDB存储引擎支持覆盖索引(covering index,或称索引覆盖),即从辅助索引中就可以得到查询记录,而不需要查询聚集索引中的记录。 - 可以减少会表查询几率

select *  from  people   where   gender ,  age ,  money注意:查询顺序abc固定为建立联合索引的顺序,若顺序混乱则无法进行查询例如:a,b,c建立联合索引,则正常可查询的如下:    where a b c    where a b非正常可查询如下:    where b c a - 无法查询    where a c b - 只能查询到a    where c - 无法查询    where b - 无法查询

四、explain(desc)命令应用 - 获取优化器选择后的执行计划

explain select * from city where countrycode='CHN'\G*************************** 1. row ***************************           id: 1  select_type: SIMPLE        table: city         type: refpossible_keys: CountryCode,idx_co_po          key: CountryCode      key_len: 3          ref: const         rows: 1        Extra: Using index condition1 row in set (0.00 sec)

五、索引结构的重要字段

5-0 查看表结构的重要字段

  • Extra - 使用的索引类型
  • key - 真正走的索引

5-1 explain 下的 type字段 - 查询SQL语句的查询类型

作用:

  1. 可以判断出,全表扫描还是索引扫描(ALL就是全表扫描,其他的就是索引扫描)
  2. 对于索引扫描来讲,又可以细划分,可以判断是哪一种类的索引扫描

 

SQL语句内的重要字段:

  • possible_keys - 可能会走的索引
  • type - 索引类型

5-1-1 ALL - 全表扫描

desc select  *  from  t1;

5-1-2 Index - 全索引扫描 - 即在覆盖索引实现查询

desc select countrycode from city ;

5-1-3 range - 索引范围扫描

  • where
    • > <  >= <=   
    • in   or   between and 
    •  like 'CH%'
  • 注意:字符的普通索引都是走的ALL类型
in 或者 or 改写成 union	select * from city where countrycode='CHN'union all select * from city where countrycode='USA';

5-1-4 ref - 辅助索引的等值查询

select * from city where countrycode='CHN'

5-1-5 eq_ref - 多表链接查询(join、on)

5-1-6 const、system - 主键或唯一键等值查询

5-2 Extra - 使用的索引决定

5-2-1 Extra下出现using  filesort - 文件排序的解决方式

!!将order by、group by 、distinct 后的列和where条件列建立联合索引!!!

转载地址:http://brlvn.baihongyu.com/

你可能感兴趣的文章
连续最大和
查看>>
不要二题目
查看>>
合法括号序列判断
查看>>
两种排序方法
查看>>
最小公倍数
查看>>
淘宝购物车测试用例
查看>>
Java语言基础(多态,抽象类,接口)
查看>>
Java语言基础(内部类,匿名内部类,object类)
查看>>
Java语言基础(数组冒泡排序,选择排序等,二分法)
查看>>
史上最全的集合(集合UML图(Collection集合和Map集合)详解,子接口(list和set)泛型)
查看>>
IO流(字节流和字符流)
查看>>
P1563 玩具谜题
查看>>
L1-002 打印沙漏 (20分)
查看>>
P1217 [USACO1.5]回文质数 Prime Palindromes
查看>>
P1014 Cantor表
查看>>
实验十 算术编码
查看>>
实验二 二维随机变量信息量的计算
查看>>
使用react脚手架创建react项目时发生错误
查看>>
关于setState是异步与同步的
查看>>
56. 合并区间---js解法
查看>>