常见的
MySQL
索引结构,hash索引
和B+树索引
hash索引
:
键值对的数据结构,且是无序排列,只能用作等值查询= 、 in
。
存在hash碰撞、不支持最左匹配原则
hash: 将不同的输入映射成独一无二的、固定长度的值("哈希值" )
hash碰撞:不同的输入得到了同一个哈希值,就发生了"哈希碰撞"(collision)
B+
: 是一种多路平衡查询树,左子节点小于父节点,父节点小于右子节点,所以比较适合于范围查询.备注1: 多个单列索引在多条件查询时优化器会选择最优索引策略,可能只用一个索引,也可能将多个索引全用上! 但多个单列索引底层会建立多个B+索引树,比较占用空间,也会浪费一定搜索效率,故如果只有多条件联合查询时最好建联合索引!
备注2: 意向锁是一种不与行级锁冲突
表级锁,即意向锁不会与行级的共享 / 排他锁互斥。
备注3: innodb引擎的每个索引列长度限制为767字节(bytes),所有组成索引列的长度和不能大于3072字节;
备注4:索引长度计算:int类型4bytes,bigint 8bytes, 字符类型的, utf8mb4:4bytes, utf8: 3bytes,gbk: 2bytes, Latin1:1bytes, 计算长度时 编码类型 * 字符长度 + (如果为变长类型+ 2)+ (如果允空 + 1)
B+树种的叶子节点可以存储整行数据也可以是主键的值
在 InnoDB 里,索引B+ Tree的叶子节点存储了整行数据的是主键索引,也被称之为
聚簇索引
。
而索引B+ Tree的叶子节点存储了主键的值的是非主键索引,也被称之为非聚簇索引
当根据主键索引查询时,直接从叶子节点获取整行数据,无需进行二次查询,效率最高
普通索引查询时,先通过索引查询到主键的值,之后再通过主键查询到对应的数据(回表查询),效率要比较低;但是也有特殊情况下不需要
进行回表查询
, 一个查询语句的执行只用从索引中就能够取得,不必从数据表中读取,就无需进行回表查询,称为索引覆盖
(要查询的数据都是索引)
1. 有主键的情况下 , 主键就是聚簇索引2. 没有主键的情况下 , 第一个非空null的唯一索引就是聚簇索引3. 如果上面都没有 , 那么就是有一个隐藏的row-id作为聚簇索引
联合索引
两个或更多个列上的索引被称作联合索引,联合索引又叫复合索引
Mysql从左到右的使用索引中的字段,一个查询可以只使用索引中的一部份,但只能是最左侧部分。例如索引是key index (a,b,c). 可以支持a | a,b| a,b,c 3种组合进行查找,但不支持 b,c进行查找 .当最左侧字段是常量引用时,索引就十分有效。
查询时where子句中使用最频繁的一列放在最左边,因为MySQL索引查询会遵循最左前缀匹配的原则,即最左优先,在检索数据时从联合索引的最左边开始匹配。所以当我们创建一个联合索引的时候,如(key1,key2,key3),相当于创建了(key1)、(key1,key2)和(key1,key2,key3)三个索引,这就是最左匹配原则
。
最左匹配原则的匹配列前缀:
如果id是字符型,那么前缀匹配用的是索引,中坠和后缀用的是全表扫描。
select * from staffs where id like 'A%';
//前缀都是排好序的,使用的都是联合索引
select * from staffs where id like '%A%';
//全表查询
select * from staffs where id like '%A';
//全表查询
MySQL5.6的
索引下推
people表中(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%'和address LIKE '%Main Street%'来判断数据是否符合条件。
如果使用了索引下推技术,则MYSQL首先会返回符合zipcode='95054’的索引,然后根据lastname LIKE '%etrunia%'和address LIKE '%Main Street%'来判断索引是否符合条件。如果符合条件,则根据该索引来定位
对应的数据,如果不符合,则直接reject掉。 有了索引下推优化,可以在有like条件查询的情况下,减少回表次数。
查询的字段需要位于索引上,才能基于索引做出LIKE判断,减少回表次数
在查询符合索引下推的情况下,查询可以把基于服务端的判断在索引上完成,从而减少查询次数。
查询优化
索引有没有生效,或者说SQL语句有没有使用索引查询
可以通过explain查看sql语句的执行计划,通过执行计划来分析索引使用情况
创建了索引,但是执行的时候并没有通过索引呢?
A:查询优化器
一条SQL语句的查询,可以有不同的执行方案,至于最终选择哪种方案,需要通过优化器进行选择,选择执行成本最低的方案。 在一条单表查询语句真正执行之前,MySQL的查询优化器会找出执行该语句所有可能使用的方案,对比之后找出成本最低的方案。这个成本最低的方案就是所谓的执行计划。 优化过程大致如下:
1、根据搜索条件,找出所有可能使用的索引
2、计算全表扫描的代价
3、计算使用不同索引执行查询的代价
4、对比各种执行方案的代价,找出成本最低的那一个