Mysql索引数据结构详解(1)

慢查询解决:使用索引

索引是帮助Mysql高效获取数据的排好序的数据结构

常见的存储数据结构:

二叉树

二叉树不适合单边增长的数据

红黑树(又称二叉平衡树)

红黑树会自动平衡父节点两边的节点数

B+树

Mysql底层用的是B+树

非叶子节点不存储data(data在Mysql中有可能是查询目标行的所有数据),

只存储索引(冗余),可以存放更多索引,减少io次数。

叶子节点包含所有索引字段

叶子节点用指针连接,提高区间访问的性能。

B+树一个节点16kb,存储一个索引需要14字节 ,故一个节点可存储1170个索引,加入子节点的存储的data加上索引的大小为1kb那么一个h为n的树科存储的数据量为1170的n次方*16,只需要高为3的树既可以存储千万级的数据量,这也是为什么mysql使用B+树作为底层数据结构实现。

在mysql中的B+树实现,在子节点子之间添加了双向指针,相当于一个双向链表,这样在进行范围查询的时候查询目标值只需要沿着指针想目标方向遍历就可以获得所有所需数据,效率极高

Hash表

hash表结构,通过hash散列算法实现,当传入一个key,通过进行hash计算获得的值,可以直接定位到指向目标的指针,并且hash结构的查询速度和数据量并非是成正比,即便是极大的数据量,hash表也可以以较快的速度获取结果,但是缺点是不支持模糊查询、范围查询这类查询方式,所以mysql百分之99的表使用B+树结构

关于mysql引擎,并非是所有mysql表都是innodb,mysql中每个表都可以单独设置数据库引擎的。比较常见的就是innodb和Myisam了

Innodb特点(聚集的):

mysql数据库中新建一个Innodb存储引擎的表,会生成2个数据文件这分别存储:

.frm存储表结构

.ibd存储索引字段和所有数据行

表数据文件本身就是按B+Tree组织的一个索引结构文件

聚集索引-叶节点包含了完整的数据记录

为什么innodb表必须有主键,并且推荐使用整型的自增主键?

答:由于innodb表数据本身就是B+组织的,所以如果不使用主键,也就没有索引,表结构无法建立,如果你不去指定主键,那么myql会隐性的建立一个rowid的字段作为主键。

因为在mysql在建立B+树的时候牵涉到大量的大小比较,如果使用UUID这种字符串类型作为主键创建索引,明显比使用整型主键作为索引要慢的多,在之后的查询中也会慢很多,并且UUID占据的存储空间也会很大。因为每个叶子节点的大小是固定,使用的主键是非递增的,当插入一个处于中间的数值是会导致已经满了的节点需要再次分裂,b+树有可能需要再次进行平衡,会占用很多时间,而使用递增主键,那么就只需要不断的在末尾子节点后面增加节点即可,减去了很多的分裂平衡的过程以及比较大小找寻插入点的时间。

为什么非主键索引结构叶子节点存储的是主键值?(一致性和节省存储空间)

答:是为了方便于保证一致性和节省存储空间。

如果在非主键索引的叶子节点也存储整行数据,这样的话在insert一个数据时就需要保证两个树结构维护完成之后才允许下面的操作,会导致在保证一致性的问题上有些复杂,并且会降低性能,还会造成数据冗余浪费存储空间。所以综合考虑之后,只在非主键索引结构中存储主键值,在通过非主键索引查询时只需要找到对应索引的主键值,在去主键索引中寻找数据即可。虽然在时间上会相比较主键索引直接查询低一些,但是避免了一致性问题和节省了存储空间。

MyIsam特点:

MyISAM索引文件和数据文件是分离的(非聚集的)

mysql数据库中新建一个MyISAM存储引擎的表,会生成3个数据文件这分别存储:

.frm存储表结构

.MYD存储表所有的数据行

.MYI存储存储索引字段

聚集索引和非聚集索引

聚集索引(聚簇索引)就是索引和数据存储在一个文件中,innodb使用的就是聚集索引

非聚集索引(稀疏索引)就是索引和数据存储在不同文件中,myisam使用的就是非聚集索引

联合索引的底层存储结构

联合索引的底层存储结构依旧是B+树。

加入有3个字段建立联合索引,那么索引中存储的就是三个字段连接在一起的数据。

那么联合索引如何去比较大小来保证一次递增的特性呢?

通过将3个字段逐个去对比,对比的次序依赖于字段在表中的顺序。

补充

1.关于mysql中索引树对于null值的处理

在mysql索引中,对于null值排序,如果是单值索引并且还是Null值,不会将null值放在非叶子节点,一般会放到叶子节点块的最前面。

对于联合索引,假如1、3索引有值,2为null值,会将2为null值的索引放在索引块的最前面,相当于当作最小值处理

来自为知笔记(Wiz)

附件列表

原文地址:https://www.cnblogs.com/qishanmozi/p/3cccdee602eeaa71c869ffb7726813ae.html

时间: 2024-10-15 09:38:54

Mysql索引数据结构详解(1)的相关文章

MySQL索引操作命令详解

创建索引: MySql创建索引的语法如下: CREATE [UNIQUE|FULLTEXT|SPATIAL] INDEX index_name [USING index_type] ON table_name (index_col_name,...) 其中对应的语法变量信息如下: [UNIQUE|FULLTEXT|SPATIAL]:中括号中的三个关键字表示创建的索引类型,他们分别表示唯一索引.全文索引.空间索引三种不同的索引类型.如果我们不指定任何关键字,则默认为普通索引. index_name

如何查看mysql数据库的引擎/MySQL数据库引擎详解

一般情况下,mysql会默认提供多种存储引擎,你可以通过下面的查看: 看你的mysql现在已提供什么存储引擎:mysql> show engines; 看你的mysql当前默认的存储引擎:mysql> show variables like '%storage_engine%'; 你要看某个表用了什么引擎(在显示结果里参数engine后面的就表示该表当前用的存储引擎):mysql> show create table 表名; MySQL数据库引擎详解 作为Java程序员,MySQL数据库

Mysql 配置参数详解以及优化配置

mysql有以下几种日志: 错误日志:   log-err 查询日志:   log 慢查询日志:  log-slow-queries 更新日志:   log-update 二进制日志: log-bin 要把日志生成在 /var/log 目录下(是系统日志存放的地方,只有 root 账号有写权限),需要 MySQL进程对这个目录有读写权限,一般是不这么做的,也考虑到安全问题,包括 MySQL 本身的数据安全,因为对 MySQL 的所有操作,都会记录到常规查询日志.MySQL的日志就不要用 /var

Mysql 三大特性详解

Mysql 三大特性详解 Mysql Innodb后台线程 工作方式 首先Mysql进程模型是单进程多线程的.所以我们通过ps查找mysqld进程是只有一个. 体系架构 InnoDB存储引擎的架构如下图所以,是由多个内存块组成的内存池,同时又多个后台线程进行工作,文件是存储磁盘上的数据. 后台线程 上面看到一共有四种后台线程,每种线程都在不停地做自己的工作,他们的分工如下: Master Thread: 是最核心的线程,主要负责将缓冲池中的数据异步刷新的磁盘,保证数据的一致性,包括脏页的刷新.合

MySQL配置文件mysql.ini参数详解、MySQL性能优化

MySQL配置文件mysql.ini参数详解.MySQL性能优化 my.ini(Linux系统下是my.cnf),当mysql服务器启动时它会读取这个文件,设置相关的运行环境参数. my.ini分为两块:Client Section和Server Section.   Client Section用来配置MySQL客户端参数.   要查看配置参数可以用下面的命令: show variables like '%innodb%'; # 查看innodb相关配置参数 show status like

MySQL中EXPLAIN详解

MySQL中EXPLAIN详解 explain显示了mysql如何使用索引来处理select语句以及连接表.可以帮助选择更好的索引和写出更优化的查询语句. 使用方法,在select语句前加上explain就可以了: 如:explain select username,first_name form hx,itlearner where a.id=b.id EXPLAIN列的解释: id:本次 select 的标识符.在查询中每个 select都有一个顺序的数值. select_type :查询类

MySQL数据库优化详解(收藏)

MySQL数据库优化详解 mysql表复制 复制表结构+复制表数据mysql> create table t3 like t1;mysql> insert into t3 select * from t1;mysql索引 ALTER TABLE用来创建普通索引.UNIQUE索引或PRIMARY KEY索引ALTER TABLE table_name ADD INDEX index_name (column_list)ALTER TABLE table_name ADD UNIQUE (colu

MySQL的binlog详解(转)

MySQL的binlog详解 什么是binlog binlog日志用于记录所有更新了数据或者已经潜在更新了数据(例如,没有匹配任何行的一个DELETE)的所有语句.语句以"事件"的形式保存,它描述数据更改. binlog作用 因为有了数据更新的binlog,所以可以用于实时备份,与master/slave复制 和binlog有关参数 log_bin 设置此参数表示启用binlog功能,并指定路径名称 log_bin_index 设置此参数是指定二进制索引文件的路径与名称 binlog_

【mysql】mysql innodb 配置详解

MySQL innodb 配置详解 innodb_buffer_pool_size:这是InnoDB最重要的设置,对InnoDB性能有决定性的影响.默认的设置只有8M,所以默认的数据库设置下面InnoDB性能很差.在只有InnoDB存储引擎的数据库服务器上面,可以设置60-80%的内存.更精确一点,在内存容量允许的情况下面设置比InnoDB tablespaces大10%的内存大小. innodb_data_file_path:指定表数据和索引存储的空间,可以是一个或者多个文件.最后一个数据文件