索引
索引概述
索引(index)是帮助MySQL高效获取数据的数据结构(有序)。在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向数据,这样就可以在这些数据结构上实现高级查找算法,这种数据结构就是索引。
索引的优缺点
优点 : 提高数据检索的效率,降低数据库的lO成本;
通过索引列对数据进行排序,降低数据排序的成本,降低CPU的消耗。
缺点: 索引列也是要占用空间的;
索引大大提高了查询效率,同时却也降低更新表的速度,如对表进行INSERT、 UPDATE、DELETE时,效率降低。
索引结构
索引是在MySQL的体系结构中的存储引擎层实现的。因此选择不同的存储引擎,索引的结构也会不同,主要包含以下几种:
B+Tree索引:最常见的索引类型,大部分引擎都支持B+树索引。
Hash索引:底层数据结构是用哈希表实现的,只有精确匹配索引列的查询才有效,不支持范围查询。
R-tree(空间索引):空间索引是MyISAM引擎的一个特殊索引类型,主要用于地理空间数据类型,通常使用较少。
Full-text(全文索引):是一种通过建立倒排索引,快速匹配文档的方式。类似于Lucene,Solr,ES。
下面列举市面上较为常见的存储引擎对索引的支持情况:
推荐一个可以动态演示数据结构的网址:Data Structure Visualization (usfca.edu)https://www.cs.usfca.edu/~galles/visualization/Algorithms.html
普通二叉树结构:
二叉树缺点:顺序插入时,会形成一个链表,查询性能大大降低。大数据量情况下,层级较深,检索速度慢。
红黑树:大数据量情况下,层级较深,检索速度慢。
B-Tree(多路平衡查找树):
B+Tree
相对于B-Tree区别:
①.所有的数据都会出现在叶子节点。
②.叶子节点形成一个单向链表。
在MySQL的B+Tree中
Hash索引的存储结构:
哈希索引就是采用一定的hash算法,将键值换算成新的hash值,映射到对应的槽位上,然后存储在hash表中。
如果两个(或多个)键值,映射到一个相同的槽位上,他们就产生了hash冲突(也称为hash碰撞),可以通过链表来解决
Hash索引的特点:
1. Hash索引只能用于对等比较(=,in),不支持范围查询(between,>,<,..)。
2.无法利用索引完成排序操作(因为Hash运算出来的结果是无序的)。
3.查询效率高,通常只需要一次检索就可以了(前提不出现Hash碰撞,不然得在链表中查找),效率通常要高于B+tree索引。
存储引擎的支持
在MysQL中,支持hash索引的是Memory引擎,而innoDB中具有自适应hash功能,hash索引是存储引擎根据B+Tree索引在指定条件下自动构建的。
这样就会出现一道面试题
为什么InnoDB引擎选择使用B+Tree索引结构?
答 :
相对于二叉树,层级更少,搜索效率高;
对于B-tree,无论是叶子节点还是非叶子节点,都会保存数据,这样导致一页中存储的键值减少,指针跟着减少,要同样保存大量数据,只能增加树的高度,导致性能降低;
相对Hash索引,B+tree支持范围匹配及排序操作;
索引分类
索引的分类一般会分为四类:
主键索引:针对于表中主键创建的索引,默认自动创建,只能有一个。
唯一索引:避免同一个表中某数据列中的值重复,可以有多个。
常规索引:快速定位特定数据,可以有多个。
全文索引:全文索引查找的是文本中的关键词,而不是比较索引中的值,可以有多个。
在InnoDB存储引擎中,根据索引的形式,又可以分为以下两种:
聚集索引(Clustered Index):将数据存储与索引放到了一块,索引结构的叶子节点保存了行数据,必须有,而且只有一个。
二级索引(Secondary Index):将数据与索引分开存储,索引结构的叶子节点关联的是对应的主键,可以存在多个。
聚集索引的选取规则
如果存在主键,主键索引就是聚集索引。
如果不存在主键,将使用第一个唯一(UNIQUE)索引作为聚集索引。
如果表没有主键,或没有合适的唯一索引,则InnoDB会自动生成一个rowid作为隐藏的聚集索引。
索引语法
创建索引:
CREATE[ UNIQUE | FULLTEXT ] INDEX index_name ON table_name ( index_col_name,...);
查看索引:
SHOW INDEX FROM table_name;
删除索引:
DROP INDEX index_name ON table_name;
SQL性能分析
我们在大多数情况下对SQL进行优化的场景是查询场景,因此如何知道一张表的DML语句分别执行了多少次尤为重要。
SQL的执行频率
SHOW GLOBAL STATUS LIKE 'Com_______'
慢查询日志
检查慢查询日志是否开启
SHOW VARIABLES LIKE 'slow_query_log';
慢查询日志记录了所有执行时间超过指定参数(long_query_time,单位:秒,默认10秒)的所有SQL语句的日志。
MySQL的慢查询日志默认没有开启,需要在MySQL的配置文件(/etc/my.cnf)中配置如下信息:
profile详情
show profiles能够在做SQL优化时帮助我们了解时间都耗费到哪里去了。通过have profiling参数,能够看到当前MySQL是否支持。
SELECT @@have_profiling;
默认profiling是关闭的,可以通过set语句在session/global级别开启profiling。
查看profiling是否打开 1 代表打开,0 代表关闭。
SELECT @@profiling;
打开profiling的命令:
SET profiling = 1;
查看执行的SQL语句的耗时情况:
SHOW PROFILES;
查看指定query_id的SQL语句各个阶段的耗时情况
show profile for query query_id;
explain执行计划
EXPLAIN或者DESC命令获取MySQL如何执行SELECT语句的信息,包括在SELECT语句执行过程中表如何连接和连接的顺序。
语法:
下篇文章会给大家带来索引的使用原则和关于如何设计索引。