「笔记很无味,点赞请准备。」node
❝数据库索引,是数据库管理系统中一个排序的数据结构,以协助快速查询,更新数据库表中的数据。mysql
❞
从定义中能够看出,索引其实就是一种「数据结构」。数据都是以文件的形式存储在磁盘上的,每一行数据都有它的磁盘地址,若是没有索引,要从几百万行数据中检索一条数据,只能遍历整张表才能找过结果。有了索引以后,只须要在索引里面去检索这条数据就能够了,由于索引是一种特殊的专门用来快速检索的数据结构,当咱们找到数据磁盘地址后,就能够拿到想要的数据。web
以InnoDB存储引擎为例,索引类型有:sql
Normal(普通索引)数据库
❝也叫非惟一索引,是最普通的索引,没有任何限制条件。微信
❞
Unique(惟一索引)数据结构
❝惟一索引要求键值不能重复。编辑器
主键索引是一种特殊的惟一索引,它多了一个限制条件,要求键值不能为空。函数
❞
Fulltext(全文索引)post
❝全文索引主要是针对比较大的数据,好比咱们存放的是消息内容,有几kb的数据,若是要解决like查询效率低的问题,能够建立全文索引。只有文本类型的字段才能够建立全文索引,好比char、varchar、text。
❞
全文索引的使用:
select * from table where match(content) against ('xxxx' IN NATURAL LANGUAGE MODE);
复制代码
汇集索引(聚簇索引)
❝汇集索引就是索引键值的逻辑顺序跟表数据行的物理存储顺序是一致的。在InnoDB中,主键索引就是汇集索引,非主键索引是非汇集索引。
❞
索引的存储模型有二分查找、二叉查找树(BST Binary Search Tree)、平衡二叉树(AVL Tree)、多路平衡查找树(B Tree)、增强版多路平衡查找树(B+ Tree)。
存储模型是一步一步演进过来的。
mysql的存储结构分为5级,表空间、段、簇、页、行。
❝表空间能够看作是InnoDB存储引擎逻辑结构的最高层,全部的数据都存放在表空间中。表空间又分为:系统表空间、独占表空间、通用表空间、临时表空间、Undo表空间。
❞
❝表空间是由各个段组成,段又分为:数据段、索引段、回滚段。
段是一个逻辑概念,一个ibd文件(独立的表空间文件)里面会有不少个段组成。
建立一个索引会建立两个段,一个是索引段(leaf node segment),一个是数据段(non-leaf node segment)。索引段管理非叶子节点的数据,数据段管理叶子节点数据。
❞
❝一个段又是由多个簇(也能够叫区)组成,每一个簇的大小是1MB(64个连续的页)。
每个段至少有个一个簇,一个段所管理的空间大小是无限的,能够一直扩展下去,扩展的最小单位就是簇。
❞
❝簇是由连续的页组成的空间,一个簇中有64个连续的页。
一个表空间最多拥有2^32个页,默认状况下一个页的大小为16KB,也就是说一个表空间最多存储64TB的数据。
❞
❝InnoDB存储引擎是面向行(Row-oriented)存储的。
❞
列的离散度
❝列的离散度计算公式:count(distinct(column_name))/count(*),列的所有不一样值和全部数据行的比例。数据行数相同的状况下,分子越大,列的离散度就越高。
简单来讲,若是列的重复值越多,离散度就越低,重复值越少,离散度就越高。
❞
联合索引最左匹配
❝联合索引在B+Tree中是复合的数据结构,它是按照从左到右的顺序来创建搜索树的。
❞
咱们在创建联合索引的时候,必定要把最经常使用的列放到最左边。
例如:给表table中创建联合索引a和b,
select * from table where a='xxx' and b='xxx' /*是能够用到联合索引的。*/
select * from table where a='xxx' /*能够用到联合索引*/
select * from table where b='xxx' /*没法使用联合索引*/
复制代码
给a和b创建联合索引其实就是至关于(a)和(a,b)创建了两个索引。
在给a、b、c创建联合索引的时候其实就是创建了(a)索引,(a,b)索引,(a,b,c)索引,这时,若是条件where b=‘xxx‘和where b=‘xxx' and c='xxx',还有where a='xxx' and c='xxx'都是用不到联合索引的。
「说明联合索引的使用条件时不能不使用第一个字段,也不能中断。」
在索引列上使用函数(「replace、substr、concat、sum、count、avg」)、表达式、计算(「+、-、*、/」)。
字符串不加引号,出现隐式转换。
like条件前面带%。
负向查询
❝not like 不能使用索引。
!=、<>、not in在某些状况下可能用到索引。
「注意:一个sql语句是否使用到索引,是跟数据库版本,数据量、数据选择度都有关系的。」
❞
其实用不用到索引,最终都是由「优化器」说了算。
「优化器是基于cost开销来决定的,怎么样开销小就怎么来。它不基于规则,也不基于语义。」
❝在辅助索引里面,不论是单列索引仍是联合索引,若是select后的数据列只要从索引中就可以获得,不用在从数据区中读取,这时候使用的索引就叫覆盖索引,这样也避免了回表。
❞
❝非主键索引,是先经过索引找到主键索引的键值,在经过主键值查出索引里面没有的数据,它比基于主键索引查询的时候多了一次查询,这个过程就是回表。
❞
❝例如:给a和b创建索引。
先根据a列从存储引擎中把符合规则的数据拉取到mysql的server层。 在server层按照b进行数据过滤。 这个过程就叫索引下推
❞