【转帖】mysql一个索引块有多少指针_深刻理解MySQL系列之索引

mysql,一个,索引,多少,指针,深刻理解,系列 · 浏览次数 : 0

小编点评

**索引** * 惟一索引:保证每一行数据的唯一性 *提升查询速度 *加速表与表的链接 *显著的减小查询中分组和排序的时间 *经过使用索引,能够在查询的过程当中,使用优化隐藏器,提升系统的性能。 **索引的优缺点** **优点** * 惟一索引:保证每一行数据的唯一性 *提升查询速度 *加速表与表的链接 **缺点** * 建索引时,须要对表加锁,在锁表的同时,可能会影响到其余的数据操做 *索引太多,维护索引须要时间跟空间 *频繁更新的数据,不宜建索引 **创建索引的注意事项** * 不要该 * 索引不是越多越好。索引太多,维护索引须要时间跟空间 * 频繁更新的数据,不宜建索引 *应该 一、重复率小的列建议生成索引

正文

索引

查找一条数据的过程

先看下InnoDB的逻辑存储结构:node

表空间:能够看作是InnoDB存储引擎逻辑结构的最高层,全部的数据都存放在表空间中。默认有个共享表空间ibdata1。若是启用innodb_file_per_table参数,须要注意每张表的表空间内存放的只是数据、索引和插入缓冲Bitmap页,其余类的数据,如回滚信息、插入缓冲索引页、系统事务信息、二次写缓冲等仍是存放在原来共享表空间中。数据库

段:

表空间是由各个段组成,常见的段有数据段、索引段、回滚段等。数据段即为B+树叶子节点(Leaf node segment),索引段即为B+树非叶子节点(Non-leaf node segment)

区性能

区:是由连续页组成的空间,在任何状况下每一个区大小都为1MB。默认状况下,存储引擎页的大小为16KB,即一个区中一共有连续64个连续的页。而为保证页的连续性,InnoDB存储引擎一次从磁盘申请4-5个区。优化

页:

页(也能够称块),是InnoDB磁盘管理的最小单位。默认每一个页大小16KB。1.2x版本后也能够经过参数innodb_page_size设置为4k、8k、16k3d

8ec87d116ce0badc66f33501adc6b490.png

如查一条数据:select * from user where id=5;指针

这里id是主键,咱们经过这棵B+树来查找,首先会去找到根页,每张表的根页位置在表空间文件中是固定的;找到根页后经过二分查找法,定位到id=5的数据应该在指针P5指向的页中,那么进一步去page number=5的页中查找,一样经过二分查询法便可找到id=5的记录:blog

ba460521cfa2132afd8c6992a3495972.png

计算一棵B+树能够存放多少行数据

也能够经过命令查看InnoDB每页默认16KB:排序

show variables like 'innodb_page_size';索引

先计算非叶子节点, 假设主键ID为bigint类型,长度为8字节,而指针大小在InnoDB源码中设置为6字节,这样一共14字节事务

而一个页中能存放多少这样的单元,其实就表明有多少指针,即16384/14=1170。

那么能够算出一棵高度为2的B+树,能存放1170*16=18720条这样的数据记录。

根据一样的原理咱们能够算出一个高度为3的B+树能够存放:1170117016=21902400条这样的记录。

因此在InnoDB中B+树高度通常为1-3层,它就能知足千万级的数据存储。

索引一些概念

聚簇索引(clustered index): 就是将索引和数据放到一块儿,找到索引也就找到了数据;以下图叶子节点存放一行全部数据。

5fe98a0bd72ae2caafb1a73f220946de.png

辅助索引(Secondary Index或非聚簇索引): 就是将数据和索引分开,查找时须要先查找到索引,而后经过索引回表找到相应的数据。

回表:先经过数据库索引扫描出数据所在的行,再经过行主键id取出索引中未提供的数据,即基于非主键索引的查询须要多扫描一棵索引树。

以下图,辅助索引查找后,会再回表到聚簇索引,最后找到数据。

1a67e15a696669dc83b023b359744f1c.png

InnoDB有且只有一个聚簇索引,而MyISAM中都是非聚簇索引。

联合索引:指对表上多个列进行索引。

联合索引的最左前缀匹配原则: 对多个字段同时创建的组合索引(有顺序,ABC,ACB是彻底不一样的两种联合索引) 以联合索引(a,b,c)为例,创建这样的索引至关于创建了索引a、ab、abc三个索引。另外组合索引实际仍是一个索引,并不是真的建立了多个索引,只是产生的效果等价于产生多个索引。

覆盖索引: 即从辅助索引中就能够获得查询的记录,而不须要查询聚簇索引中的记录。

使用覆盖好处:

辅助索引不包含整行记录的全部信息,故其大小要远小于聚簇索引,减小大量IO操做。

对某些统计(如count(id))并不会经过查询聚簇索引来进行统计,减小IO操做

惟一索引:以惟一列生成的索引,该列不容许有重复值,但容许有空值(NULL)

索引下推:MySQL 5.6引入了索引下推优化,能够在索引遍历过程当中,对索引中包含的字段先作判断,过滤掉不符合条件的记录,减小回表字数。

为何选B+树,而不是B树

B树无论叶子节点仍是非叶子节点,都会保存数据,这样致使在非叶子节点中能保存的指针数量变少

指针少的状况下要保存大量数据,只能增长树的高度,致使IO操做变多,查询性能变低;

为何InnoDB只有一个聚簇索引,而不将全部索引都使用聚簇索引?

由于聚簇索引是将索引和数据都存放在叶子节点中,若是全部的索引都用聚簇索引,则每个索引都将保存一份数据,会形成数据的冗余,在数据量很大的状况下,这种数据冗余是很消耗资源的。

什么状况下会发生明明建立了索引,可是执行的时候并无经过索引呢?

查询优化器。

一条SQL语句的查询,能够有不一样的执行方案,至于最终选择哪一种方案,须要经过优化器进行选择,选择执行成本最低的方案。

优化过程大体以下:

一、根据搜索条件,找出全部可能使用的索引

二、计算全表扫描的代价

三、计算使用不一样索引执行查询的代价

四、对比各类执行方案的代价,找出成本最低的那一个 。

索引的优缺点

索引的优势以下:

一、惟一索引能够保证每一行数据的惟一性

二、提升查询速度

三、加速表与表的链接

四、显著的减小查询中分组和排序的时间

五、经过使用索引,能够在查询的过程当中,使用优化隐藏器,提升系统的性能。

索引的缺点以下:

建立索引时,须要对表加锁,在锁表的同时,可能会影响到其余的数据操做

虽然索引大大提升了查询速度,同时却会下降更新表的速度,如对表进行 INSERT、UPDATE 和 DELETE。由于更新表时,MySQL 不只要保存数据,还要保存索引文件。

创建索引会占用磁盘空间的索引文件。通常状况这个问题不算严重,但若是你在一个大表上建立了多种组合索引,且伴随大量数据量插入,索引文件大小也会快速膨胀。

若是某个数据列包含许多重复的内容,为它创建索引就没有太大的实际效果。

对于很是小的表,大部分状况下简单的全表扫描更高效。

使用索引时的注意事项

原则:

不该该

一、索引不是越多越好。索引太多,维护索引须要时间跟空间

二、 频繁更新的数据,不宜建索引。

三、数据量小的表不必创建索引。

应该

一、重复率小的列建议生成索引。由于重复数据少,索引树查询更有效率,等价基数越大越好。

二、数据具备惟一性,建议生成惟一性索引。在数据库的层面,保证数据正确性

三、频繁group by、order by的列建议生成索引。能够大幅提升分组和排序效率

四、常常用于查询条件的字段建议生成索引。经过索引查询,速度更快

索引失效的场景

一、模糊搜索:左模糊或全模糊都会致使索引失效,好比'%a'和'%a%'。可是右模糊是能够利用索引的,好比'a%'

二、隐式类型转换:好比select * from t where name = xxx , name是字符串类型,可是没有加引号,因此是由MySQL隐式转换的,因此会让索引失效

三、当语句中带有or的时候:好比select * from t where name=‘sw’ or age=14

四、不符合联合索引的最左前缀匹配:(A,B,C)的联合索引,你只where了C或B或只有B,C

其余注意事项:

索引不会包含有 null 值的列,只要列中包含有 null值都将不会被包含在索引中。

使用短索引。短索引不只能够提升查询速度并且能够节省磁盘空间和 I/O 操做

索引列排序。查询只使用一个索引,所以若是 where 子句中已经使用了索引的话,那么 order by 中的列是不会使用索引的。所以数据库默认排序能够符合要求的状况下不要使用排序操做;尽可能不要包含多个列的排序,若是须要最好给这些列建立复合索引。

不要在列上进行运算,这将致使索引失效而进行全表扫描

不使用 not in 和 <> 操做,这不属于支持的范围查询条件,不会使用索引。

文章知识点与官方知识档案匹配,可进一步学习相关知识
MySQL入门技能树深入索引隐藏索引57294 人正在系统学习中

与【转帖】mysql一个索引块有多少指针_深刻理解MySQL系列之索引相似的内容:

【转帖】mysql一个索引块有多少指针_深刻理解MySQL系列之索引

索引 查找一条数据的过程 先看下InnoDB的逻辑存储结构:node 表空间:能够看作是InnoDB存储引擎逻辑结构的最高层,全部的数据都存放在表空间中。默认有个共享表空间ibdata1。若是启用innodb_file_per_table参数,须要注意每张表的表空间内存放的只是数据、索引和插入缓冲B

[转帖]mysql中innodb创建表的一些限制

https://www.cnblogs.com/jackssybin/p/16258953.html 1、 背景 在新创建mysql数据表的时候。不太确定表能创建多少个字段,多少个索引。索引多少有限制么?mysql的数据是怎么存储的存在在哪里。 2、基本个数限制 在MySQL5.6.9以后的版本,一

【转帖】查看mysql库大小,表大小,索引大小

https://www.cnblogs.com/lukcyjane/p/3849354.html 说明: 通过MySQL的 information_schema 数据库,可查询数据库中每个表占用的空间、表记录的行数;该库中有一个 TABLES 表,这个表主要字段分别是: TABLE_SCHEMA :

【转帖】MySQL索引

数据表如何用索引快速查找 索引是 排好序的快速查找的数据结构 索引存储在文件系统中 索引的文件存储形式与存储引擎有关 索引数据结构:可以是二叉树、红黑树、Hash表、B-Tree、B+Tree 1、二叉树 使用索引的如下图:(如果是使用二叉树结构)每一个节点都存放数据行的磁盘地址【快速定位到数据】

[转帖]MySQL提升笔记(4)InnoDB存储结构

https://cdn.modb.pro/u/310923 这一节本来计划开始索引的学习,但是在InnoDB存储引擎的索引里,存在一些数据存储结构的概念,这一节先了解一下InnodDB的逻辑存储结构,为索引的学习打好基础。 从InnoDB存储引擎的存储结构看,所有数据都被逻辑地放在一个空间中,称之为

[转帖]在 TiDB 中正确使用索引,性能提升 666 倍

https://tidb.net/book/tidb-monthly/2022/2022-04/usercase/index-666 背景​ 最近在给一个物流系统做TiDB POC测试,这个系统是基于MySQL开发的,本次投入测试的业务数据大概10个库约900张表,最大单表6千多万行。 这个规模不算

[转帖]【MySQL 8】MySQL 5.7都即将停只维护了,是时候学习一波MySQL 8了

https://www.cnblogs.com/paul8339/p/17026571.html 阅读目录 账户与安全 索引增强 原子DDL操作 通用表达式(CTE) 其他 MySQL 8新特性选择MySQL 8的背景:MySQL 5.6已经停止版本更新了,对于 MySQL 5.7 版本,其将于 2

[转帖]MySQL索引优化分析之性能分析(Explain执行计划)

一、MySQL常见瓶颈 二、性能分析工具Explain(执行计划 ) 使用EXPLAIN关键字可以模拟优化器执行SQL查询语句,从而知道MySQL是如何处理你的SQL语句的。分析你的查询语句或是表结构的性能瓶颈。查看官网说明: 使用: Explain + SQL语句 作用: 三、各字段解释 3.1、

【转帖】MySQL InnoDB存储原理深入剖析与技术分析

一、MySQL记录存储: MySQL InnoDB的数据由B+树来组织,数据记录存储在B+树数据页(page)中,每个数据页16kb,数据页 包括页头、虚记录、记录堆、自由空间链表、未分配空间、slot区、页尾七部分组成。 所有的非终端结点可以看成是索引部分,结点中仅含有其子树根结点中最大(或最小)

[转帖]深入理解mysql-第六章 mysql存储引擎InnoDB的索引-B+树索引

一、引入索引 在没有索引的情况下,不论是根据主键列或者其他列的值进行查找,由于我们并不能快速的定位到记录所在的页,所以只能从第一个页沿着双向链表一直往下找,因为要遍历所有的数据页,时间复杂度就是O(n),所以这种方式显然是超级耗时的。所以我们需要采取一定的数据结构来存储数据,方便我们进行数据的增删改