IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 索引详细了解 -> 正文阅读

[数据结构与算法]索引详细了解

目录

索引

概述

MySQL索引原理和数据结构介绍

存储位置

局部性原理:

磁盘预读

数据结构(B+树 )

哈希表

存储引擎(数据文件在存储介质中的不同组织形式)

树(二叉树、BST、AVL、红黑树、B树、B+树)

B树、B+树

MySQL聚簇索引和非聚簇索引区别?

关于索引的技术名词

IO

MySQL


索引

概述

索引是帮助MySQL高效获取数据的数据结构

MySQL索引原理和数据结构介绍

存储位置

索引的数据文件也需要持久化存储,存储到磁盘中,当需要时把数据从磁盘中读取到内存中,加快数据的访问(分块读取)

局部性原理:

数据和程序都有聚集成群的倾向,之前被查过的数据很快会被再次查询,冷热数据

磁盘预读

在数据交换的时候,会有一个基本的逻辑单位,称之为页,一般占用空间是4K/8K,跟操作系统相关,每次在进行数据获取的时候,可以获取页的整数倍(读取数据时,以页的整数倍读取数据,MySQL中innodb的存储引擎读取数据的时候会读取16K(innodb_page_size value=16K))

数据结构(B+树 )

K-V格式的数据:哈希表、树

哈希表

hashmap用的红黑树

缺点:

  1. 范围查找需要遍历每一个元素,如果全部是等值查找可以用Hash表

  2. 碰撞--冲突:数据散列不均匀,浪费存储空间,因此要求设计足够好的hash算法

  3. 如果存储大量数据,会占用大量的存储空间,而且不能够分块读取

存储引擎(数据文件在存储介质中的不同组织形式)

  • innodb

  • MyISAM

  • memory (hash索引,MySQL官网介绍)

(二叉树、BST、AVL、红黑树、B树、B+树)

  • 二叉树、BST、AVL、红黑树 二叉树有且仅有两个分支

  • BST、AVL、红黑树 有序二叉树

  • AVL、红黑树 二叉平衡树

B树、B+树

多叉有序树

degree:阶/度,表示每个节点至多存放多少条记录(degree=4,最多插入3条,插入第四条开始分支)

B树:

16:键值,即表中记录的主键

P:指针,存储子节点地址信息

data:数据,即表记录中处主键外的数据

B+树:

B+树每个节点可以包含更多的节点,这么做的原因有:

  1. 降低树的高度

  2. 将数据范围变为多个区间,区间越多,数据检索越快

非叶子节点存储key,叶子节点存储key和数据

叶子节点两两指针相互连接(符合磁盘的预读特性),顺序查询性能更高

MySQL数据层数:千万级别三到四层,key要尽可能少的占用空间,所以int比varchar好

MySQL聚簇索引和非聚簇索引区别?

判断数据和索引是否放在一起,放在一起就是聚簇索引,不放在一起就是非聚簇索引

在innodb中,数据在进行插入的时候必须要跟某一个索引的值进行绑定,这个值默认是主键,如果没有主键,选择唯一键,没有唯一键选择六字节的rowid。→数据一定跟索引存放(.frm .ibd)

一个表中可以有多少个索引?

索引如果是跟数据放在一起的话,数据会只存储一份

id,name,age,gender,address,id是主键,name是普通索引→

在整个表中会有两个B+树,主键是跟数据放在一起的,name所在的B+树叶子节点中放置的是id的值。

select * from table where name=?→执行这个语句会走两科B+树,先根据nameB+树检索到id值,再根据id值到idB+树检索到整体行记录

由上得到结论:innodb中一定有聚簇索引(id是聚簇索引,name是非聚簇索引),但是其他索引都是非聚簇索引

MyISAM只有非聚簇索引

关于索引的技术名词

id,name,age,gender    id是主键,name是普通索引

回表

select * from table where name='小美女'
从非聚簇索引跳转到聚簇索引中查找数据的过程称为回表,效率不高,因此在工作中避免回表操作

索引覆盖

select id,name from table where name='小美女'
当非聚簇索引的叶子节点中包含了查询需要的所有字段时,不需要回表,这个过程称为索引覆盖,推荐使用索引覆盖

最左匹配

id,name,age,gender    id是主键,name,age是普通索引,组合索引

除了第三条都符合最左匹配(从name到age,先过滤name)

第四条MySQL优化器会优化为先name后age

select * from table where name=?  and age=?
select * from table where name=?
select * from table where age=?
select * from table where age=?  and name=?

索引下推

select * from table where name=?  and age=?
在没有索引下推之前,执行过程是先根据name从存储引擎中拉取数据,然后根据age在server中过滤
有了索引下推后,执行过程是根据(name,age)整体的从存储引擎中做数据检索,返回对应的记录,不在server层做任何操作(把检索内容从server层推到存储引擎层)

案例1

创建表abc,id主键索引,a、b、c为组合索引idx_1

CREATE TABLE abc(id INT PRIMARY KEY,a INT,b INT,c INT);
ALTER TABLE abc ADD INDEX idx_1(a,b,c);
SHOW INDEX FROM abc;
EXPLAIN SELECT * FROM abc WHERE a=1 AND b=1 AND c=1;
EXPLAIN SELECT * FROM abc WHERE b=1 AND c=1;
EXPLAIN SELECT * FROM abc WHERE c=1;

三个查询都用到了索引

当表中的全部列(除主键索引列外)都是组合索引列的时候,无论怎么查都会用到索引

案例2

创建表abcd,id主键索引,a、b、c为组合索引idx_2,d无索引

CREATE TABLE abcd(id INT PRIMARY KEY,a INT ,b INT,c INT ,d INT);
ALTER TABLE abcd ADD INDEX idx_2(a,b,c);
SHOW INDEX FROM abcd;
EXPLAIN SELECT * FROM abcd WHERE a=1 AND b=1 AND c=1 AND d=1;用到了索引
EXPLAIN SELECT * FROM abcd WHERE b=1 AND c=1 AND d=1;没用到索引
EXPLAIN SELECT * FROM abcd WHERE c=1 AND d=1;没用到索引
EXPLAIN SELECT * FROM d=1;没用到索引

案例3

创建表abc,id主键索引,a、b、c为组合索引 idx_2,d为普通索引 idx_3

ALTER TABLE abcd ADD INDEX idx_3(d);
EXPLAIN SELECT * FROM abcd WHERE id=1;-- (当表为空时没有用到主键索引)用到主键索引,索引长度4
EXPLAIN SELECT * FROM abcd WHERE d=1; -- 用到索引idx_3,索引长度5
EXPLAIN SELECT * FROM abcd WHERE a=1 AND b=1 AND c=1;-- 用到索引idx_2索引长度15
EXPLAIN SELECT * FROM abcd WHERE a=1 AND b=1;-- 索引长度10
EXPLAIN SELECT * FROM abcd WHERE a=1;-- 索引长度5
EXPLAIN SELECT * FROM abcd WHERE b=1 AND c=1;-- 没有用到索引
EXPLAIN SELECT * FROM abcd WHERE c=1;-- 没有用到索引
EXPLAIN SELECT * FROM abcd WHERE a=1 AND c=1;-- 用到索引idx_2 索引长度5

案例4

创建表abc,id主键索引,a、b、c、d为组合索引idx_2

ALTER TABLE abcd ADD INDEX idx_2(a,b,c,d);
EXPLAIN SELECT * FROM abcd WHERE d=1;-- 用到了idx_2索引,索引长度20
EXPLAIN SELECT * FROM abcd WHERE c=1;-- 用到了idx_2索引,索引长度20
EXPLAIN SELECT * FROM abcd WHERE b=1;-- 用到了idx_2索引,索引长度20
EXPLAIN SELECT * FROM abcd WHERE a=1;-- 用到了idx_2索引,索引长度5
EXPLAIN SELECT * FROM abcd WHERE a=1 AND b=1;-- 用到了idx_2索引,索引长度10
EXPLAIN SELECT * FROM abcd WHERE a=1 AND b=1 AND c=1;-- 用到了idx_2索引,索引长度15
EXPLAIN SELECT * FROM abcd WHERE a=1 AND b=1 AND c=1 AND d=1;-- 用到了idx_2索引,索引长度20
EXPLAIN SELECT * FROM abcd WHERE a=1 AND b=1 AND d=1;-- 用到了idx_2索引,索引长度10
EXPLAIN SELECT * FROM abcd WHERE id=1;-- 用到了主键索引,索引长度为4

IO

IO是硬件层面的瓶颈,软件方面有IO量和IO次数

减少IO量、减少IO次数,公司禁止写select *(IO量增多)

MySQL

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-07-31 16:53:22  更:2021-07-31 16:54:54 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 16:30:18-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码