01 索引概述
【1】概念:索引就是一种有序的数据结构,可用于高效查询数据。在数据库表中除了要保存原始数据外,数据库还需要去维护索引这种数据结构,通过这种数据结构来指向原始数据,这样就可以根据这些数据结构实现高级查找算法。(总之就是把表中的数据存储在数据结构中了)
【2】无索引和有索引的区别:(下图中二叉树索引结构并不是真实的索引结构,只是打个比方)
① 无索引:一个一个数据进行遍历,即使找到了,也会把整张表遍历完。
② 有索引:会在利用数据结构存储表中相关数据,以及数据所指向的地址。
【3】索引的优点:① 提高查询效率 ② 提高排序效率
【4】索引的缺点(可以忽略):① 索引要占用磁盘空间(磁盘现在很便宜) ② 增删改的效率低(业务操作中其实增删改的操作比例很小)
02 索引结构
02_01 介绍与支持
【1】索引是在存储引擎层实现的,不同的存储引擎有不同的索引结构。
【2】索引结构:
B+tree类型的索引结构常用的存储引擎都支持,且是InnoDB存储引擎默认的索引结构。
Hash索引性能高但不支持范围查询,只支持精确匹配。
【3】不同的存储引擎对索引结构的支持情况:
【4】如果没有指定是哪种存储引擎的哪种索引结构,则默认说的是B+tree索引。工作、面试问的索引问的是B+tree索引。
02_02 B树的演变过程
11. 进阶-索引-结构-Btree_哔哩哔哩_bilibili
02_03 B+树的演变过程
12. 进阶-索引-结构-B+tree_哔哩哔哩_bilibili
【1】所有的元素都会出现在叶子节点。
【2】非叶子节点只是起索引的作用。
【3】所有的叶子节点构成了一个单项链表。
02_04 MySQL中B+tree索引结构
【1】在B+tree基础上将所有的叶子节点构成了一个双向链表。
【2】每一个节点都存储在一个页中(表空间段区页行),且一个页的大小在InnoDB中是16K。
02_05 Hsh索引结构
02_06 InnoDB为啥使用B+tree索引
① 二叉树,顺序插入时,会形成一个链表,查询性能低。
② 红黑树,大数据量的情况下,层级较深,检索速度慢。
③ B树,叶子节点和非叶子节点都会存放数据,而每一个节点存储在的页空间是有限的,如果非叶子节点不存放数据,则存储每个非叶子节点的页空间变增多,此时就可以存放更多的key和指针,key和指针增多了,最终相同数据量的情况下,使用B+tree的深度会浅一些。
④ hash索引结构,hash索引只支持等值匹配,并不支持范围匹配和排序操作的。
03 索引分类
【思考问题】:
解答:假设每一行数据大小为1k,而每个页的大小为16k,所以一个页能存16行数据。
如果B+tree高度为2,设一个页中可以存放n个key,n*8+(n+1)*6=16*1025,n = 1170
此时叶子节点的个数为1171,可存放行数为1171*16 = 18736
04 索引语法
【1】在创建索引时,一个索引可以关联多个字段。如果一个索引只关联一个字段,这种索引称为单列索引;如果一个索引只关联了多个字段,这种索引称为联合索引/组合索引,注意:联合索引的顺序是有要求的。
05 SQL性能分析工具
【为什么要学,SQL性能分析的工具】:因为我们要做SQL优化,要做SQL优化首先得定位到要对那个类型的SQL进行优化,这时候我们就得知道每个SQL的执行性能是怎样的。在做SQL优化的时候,我们优化的主要是与查询有关的SQL,而在优化查询语句时对索引的优化其实占主导地位。
05_01 SQL执行频率
【为什么要知道SQL的执行频率】:假如有一个业务系统,这个业务系统有一个数据库,数据库里面表中的数据量特别大,但这张表只做插入,不做查询,那我们对索引进行优化是没必要的。
【查询全局/当前回话的状态信息】:
05_02 慢查询日志
【1】我们知道了SQL执行频率,就知道了哪一类语句执行频率高,如果想进一步知道执行频率高的语句里是哪些具体的语句执行效率低,就需要用到慢查询日志。
【2】概念:可以用来记录语句执行时间超过指定参数long_query_time,单位秒,默认10s,的所有SQL语句。
【3】MySQL的慢查询日志默认是关闭的,查看开关情况:show variables like 'slow_query_log'
打开慢查询日志需要在MySQL的配置文件(/etc/my.cnf)中配置如下信息:
slow_query_log=1
long_query_time=2
【具体步骤】:
以root用户登录linux命令行,输入vi /etc/my.cnf ---》按G ---》然后按一下s ---》然后写配置信息 --》然后按ins、esc --》在命令行中写:x,保存并关闭
重启mysql服务器:systmctl restart mysql
查看慢查询日志中记录的信息:以root用户登录linux命令行 ---》cd /va/lib/mysql ---》ll ---》cat localhost-slow.log
05_03 profile详情
【1】加入有些语句业务很简单,但是执行的时间为1.8s,这类的SQL性能也会认为是很低的,我们也需要对这一类的SQLj进行优化
【2】select @@have_profiling; 查看当前数据库是否支持profile
数据库的profile开关默认是关着的,查看profile开关情况:select @@profiling;
开启开关:set session/global profiling = 1;
【3】查看当前回话中,所有SQL的耗时情况:show profiles;
【4】查询指定query_id的SQL语句各阶段的耗时情况:show profile for query query_id;
【5】查询指定query_id的SQL语句CPU的使用情况:show profile cpu for query query_id;
05_04 explain执行计划
【1】概念:通过explain 或者 desc 命令可以获取某条 select 语句的执行计划,从而评定某条select语句的执行性能。
【2】语法:在任意的select语句之前加上explain / desc
06 索引使用
06_01 最左前缀法则(索引失效)
【说明】:
① 针对于联合索引(一个索引关联了多个字段)
② 我们在查询数据时,如果可以根据索引来查,就根据索引来查,如果无法根据索引就进行全表扫描
③ 最左前缀法则:使用的联合索引最左列必须存在(注意:这里说的索引最左列不是说你写的where语句中的顺序,而是索引名中字段的顺序),否则进行全表扫描;如果跳过了索引中的列,则该索引后面的字段会失效。
06_02 范围查询右侧的列索引失效(索引失效)
【说明】:
① 和最左前缀法则一样,针对的是联合索引
② 范围查询右侧的列索引失效:在联合索引中,出现了某字段使用了>,<的比较,则该字段后面的索引将失效
③ 如何规避:在业务允许的条件下,尽量使用>=,<=
06_03 不要在索引列上进行运算操作否则索引失效(索引失效)
06_04 字符串类型不加引号查询索引将会失效(索引失效)
06_05 模糊查询(索引失效)
【说明】:如果仅仅是尾部模糊匹配,索引不会失效,如果是头部模糊匹配,索引会失效。
06_06 or连接的条件(索引失效)
只有or的两侧都有索引的时候,索引才会失效。
06_07 数据分布的影响(索引失效)
06_08 SQL提示
【说明】:在可以使用多个索引的情况下,指定使用哪个索引,指定不使用哪个索引,指定必须使用哪个索引。(如果只是指定,并不强制,则MySQL也会去自己权衡到底使用哪一个)
06_09 覆盖索引
【说明】:尽量避免使用select *