Mysql进阶(上) -- 存储引擎,索引

 Seasons in the Sun - Westlife - 单曲 - 网易云音乐

目录 -- 查看左栏

目录

存储引擎

Mysql体系结构

简介

InnoDB介绍

MyISAM和Memory

选择

小结

Mysql安装(linux版本)

索引

概述

结构 - 介绍

结构 - Btree

结构 - B+tree

结构 - hash

索引 - 结构 - 面试题

分类

面试题

语法

性能分析 - 查看执行频次

性能分析 - 慢查询日志

一,慢查询配置 

二,慢查询查看

三,导入1000万数据

四,再次查询

ฅʕ•̫͡•ʔฅ关于[root@192~] 和 mysql>


来自黑马Mysql,只用作学习,链接 -> 11. 进阶-索引-结构-Btree_哔哩哔哩_bilibili

 一个深爱的女孩 - 本兮 - 单曲 - 网易云音乐

存储引擎

Mysql体系结构

Mysql进阶(上) -- 存储引擎,索引_第1张图片

Mysql进阶(上) -- 存储引擎,索引_第2张图片

简介

Mysql进阶(上) -- 存储引擎,索引_第3张图片

use itcast;

-- 查询建表语句   -- 默认存储引擎:InnoDB
show create table account;

-- 查询当前数据库支持的存储引擎
show engines;

-- 创建表 my_myisam,并指定MyISAM存储引擎
create table my_myisam(
    id int,
    name varchar(10)
) engine = MyISAM;

-- 创建表 my_memory,并指定Memory存储引擎
create table my_memory(
    id int,
    name varchar(10)
) engine = memory;

InnoDB介绍

Mysql进阶(上) -- 存储引擎,索引_第4张图片Mysql进阶(上) -- 存储引擎,索引_第5张图片

-- 查看系统变量
show variables like 'innodb_file_per_table';

MyISAM和Memory

Mysql进阶(上) -- 存储引擎,索引_第6张图片

Mysql进阶(上) -- 存储引擎,索引_第7张图片

Mysql进阶(上) -- 存储引擎,索引_第8张图片

一道面试题,考察InnoDB和MySIAM的区别

选择

Mysql进阶(上) -- 存储引擎,索引_第9张图片

InnoDB是大多数开发的选择,而MyISAM和Memory被NoSQL系列的数据库替代了

具体的说,myisam被mongoDB取代了,Memory被Redis取代了

小结

Mysql进阶(上) -- 存储引擎,索引_第10张图片

Mysql安装(linux版本)

B站,Google,百度,GPT

翻烂了,才搞定这部分,放几个链接(虚拟机真的老大难,按着教程来一直有BUG,一个是有些细节没讲到,比如默认设置需要自己改,比如Centos7的版本和22年之前甚至22年的版本都不太一样.....不过摸索一次也是锻炼。以后要外网访问项目还可以买服务器,或者内网穿透)

ubuntu和centos教程B站有,其他的问gpt和goole,百度就行

安装了虚拟机,VMware里弄了Ubuntu和Centos

(1)

08. 进阶-MySQL安装(linux版本)_哔哩哔哩_bilibili

(2)
(1条消息) 《Linux篇》超详细安装FinalShell并连接Linux教程_finalshell连接linux_陈老老老板的博客-CSDN博客

(3)

centos7如何查看ip信息(centos 6.5以前都可以用ifconfig 但是centos 7里面没有了,centos 7用什么查看?)_51CTO博客_centos7 查看IP

(4)

centos7怎么查看ip地址 - 掘金 (juejin.cn)

(5)

关于VM虚拟机(Finalshell的连接问题)_finalshell连接不上虚拟机_unique馒头的博客-CSDN博客

(6)

Linux查询ip地址ens33没有inet这个属性_Mr.Bh的博客-CSDN博客

终于用finalshell连接上CentOS了....弄了一天..... 

Mysql进阶(上) -- 存储引擎,索引_第11张图片

上面只弄了第1步,后续的比较简单,跟着视频就行

08. 进阶-MySQL安装(linux版本)_哔哩哔哩_bilibili

第5步,安装Mysql安装包

rpm -ivh mysql-community-common-8.0.26-1.e17.x86_64.rpm

rpm -ivh mysql-community-client-plugins-8.0.26-1.e17.x86_64.rpm

rpm -ivh mysql-community-libs-8.0.26-1.e17.x86_64.rpm

rpm -ivh mysql-community-libs-compat-8.0.26-1.e17.x86_64.rpm

rpm -ivh mysql-community-devel-8.0.26-1.e17.x86_64.rpm

yum remove mysql-libs

...

(12)DataGrip远程连接Mysql

关闭Linux的防火墙:步骤与必要性(关闭linux的防火墙)-数据库远程运维 (dbs724.com)

在Finalshell关闭Linux防火墙,才可以连接成功

Mysql进阶(上) -- 存储引擎,索引_第12张图片

索引

概述

Mysql进阶(上) -- 存储引擎,索引_第13张图片

索引是一种,高效获取数据,的数据结构

Mysql进阶(上) -- 存储引擎,索引_第14张图片

上述二叉树索引结构,只是示意图,并非真实索引结构

Mysql进阶(上) -- 存储引擎,索引_第15张图片

索引能提高 的效率,但是会降低 增删改 的效率,当然,对于大部分业务,查询占比大的多

结构 - 介绍

Mysql进阶(上) -- 存储引擎,索引_第16张图片

主要学习B+Tree,其次是Hash索引

Mysql进阶(上) -- 存储引擎,索引_第17张图片

结构 - Btree

Mysql进阶(上) -- 存储引擎,索引_第18张图片

左子树都小于根节点,右子树都大于根节点

Mysql进阶(上) -- 存储引擎,索引_第19张图片

同样是左小右大

n个key,n + 1个指针

比如5阶的BTree,每个节点最多4个key

下面演示BTree构造的过程

黑马 -- 数据结构可视化链接:

B-Tree Visualization (usfca.edu)  and Data Structure Visualization (usfca.edu)

或者用我之前推荐的:数据结构和算法动态可视化 (Chinese) - VisuAlgo

核心是,某个节点达到最大的key时,中间元素向上分裂

Mysql进阶(上) -- 存储引擎,索引_第20张图片

已经插入很多数据,下面演示再插入个2456的变化

(1)

Mysql进阶(上) -- 存储引擎,索引_第21张图片

(2)

Mysql进阶(上) -- 存储引擎,索引_第22张图片

(3)

Mysql进阶(上) -- 存储引擎,索引_第23张图片

这就是BTree的演变过程,每一个key下都会挂对应的数据

结构 - B+tree

(1)所有元素都会出现在叶子节点,上面的元素只是起到索引的作用

(2)叶子节点是单向链表的形式

下面进行演示,B+ Tree Visualization (usfca.edu)

先准备一个5阶的B+Tree

Mysql进阶(上) -- 存储引擎,索引_第24张图片

当我们插入890

(1)

(2)

Mysql进阶(上) -- 存储引擎,索引_第25张图片

中间元素567向上裂变时,叶子节点也会插入567(中间元素)

-------------------------

再举个例子,初始

Mysql进阶(上) -- 存储引擎,索引_第26张图片

插入2345

(1)

Mysql进阶(上) -- 存储引擎,索引_第27张图片

(2)

Mysql进阶(上) -- 存储引擎,索引_第28张图片

B+Tree与BTree区别

Mysql进阶(上) -- 存储引擎,索引_第29张图片

再看看Mysql中的B+Tree

Mysql进阶(上) -- 存储引擎,索引_第30张图片

叶子节点类似,双向循环链表。

注意,数据都存储在叶子节点

结构 - hash

Mysql进阶(上) -- 存储引擎,索引_第31张图片

Mysql进阶(上) -- 存储引擎,索引_第32张图片

索引 - 结构 - 面试题

(1)为什么InnoDB存储引擎采取B+Tree,而不采取二叉树,红黑树?

因为二叉树在,顺序插入时,会形成一条链表,搜索时性能极低,红黑树本质也是二叉树

而B+Tree在插入元素时,某一节点达到最大的key后,中间元素会向上分裂,所以层级更少,效率更高

(2)为什么也不采取BTree呢?

----------------------------  分界线

BTree可视化

B-Tree Visualization (usfca.edu)

B+Tree可视化

B+ Tree Visualization (usfca.edu)

BTree与B+Tree区别

Difference between B tree and B+ tree - GeeksforGeeks

----------------------------  分界线

这里作个区分,下面是B-Tree的,这个是B+Tree的

Mysql进阶(上) -- 存储引擎,索引_第33张图片Mysql进阶(上) -- 存储引擎,索引_第34张图片

B-Tree和B+Tree的共同特点:

with the lowest value on the left and the highest value on the right

区别:

B+ tree eliminates the drawback B-tree used for indexing by storing data pointers only at the leaf nodes of the tree(B+ 树只在树的叶节点存储数据指针,消除了 B 树用于索引的缺点)

换言之,B-Tree非叶子节点也存放数据,但非叶子节点只起到了索引的效果(叶子节点会存放所有数据),而每个节点只能存放一页的数据,也就是16K,相同数据量,B-Tree的层级会更深

另外,B+Tree查找数据,只需要在叶子节点查找,搜索效率更稳定

补充,B+Tree叶子节点,会形成双向循环链表,便于范围搜索排序

(3)为什么不用hash索引?

hash只支持等值匹配 (=, in),不支持范围匹配 (>=, <) 和排序操作 

Mysql进阶(上) -- 存储引擎,索引_第35张图片

分类

Mysql进阶(上) -- 存储引擎,索引_第36张图片

InnoDB存储引擎中,根据索引的存储形式可分为:

Mysql进阶(上) -- 存储引擎,索引_第37张图片

对聚集索引和二级索引的区分

Mysql进阶(上) -- 存储引擎,索引_第38张图片Mysql进阶(上) -- 存储引擎,索引_第39张图片

有主键的话,主键索引就是聚集索引,而聚集索引叶子节点,下面挂的row就是所在行的数据

Mysql进阶(上) -- 存储引擎,索引_第40张图片

而二级索引,叶节点下挂的值,是所在行的 id 值

举例说明如何查询

select * from user where name = 'Arm';

(1)先从二级索引开始,逐个对比,直到找到Arm,此时我们需要查找的是 *,需要输出整行的数据,根据Arm得到了这一行的 id 10

(2)然后到聚集索引,逐个对比,定位到10后,就拿到了这一行的数据

(1)和(2)的整个过程叫 --> “回表查询

回表查询:先从二级索引找到对应的主键值,再根据主键值从聚集索引中,得到这一行的行数据

再次强调,聚集索引叶节点 --> 行数据二级索引叶节点 --> id

面试题

(1)以下SQL语句,哪个执行效率更高,为什么

Mysql进阶(上) -- 存储引擎,索引_第41张图片备注:id为主键,name字段创建的有索引

1,根据 id = 10,直接到聚集索引中对比,就能查到 * ,只需要扫描1次

2,但是根据 name,得先到二级索引得到 id,再到聚集索引扫描1次,也就是需要回表查询

(2)InnoDB主键索引 B+Tree的高度为多少

Mysql进阶(上) -- 存储引擎,索引_第42张图片

Mysql进阶(上) -- 存储引擎,索引_第43张图片

InnoDB指针占用6字节空间,主键如果为int,占用4字节;如果为bigint,占用8字节

(我们假设主键为bigint)一个主键占用8字节

当树的高度 = 2

已知,指针比key多一个,假设主键n个

n * 8 + (n + 1) * 6 即key和指针所占用的总空间,又1页的大小16k,1k = 1024字节

n * 8 + (n + 1) * 6 = 16 * 1024,所以n ≈ 1170

因为一个节点放在磁盘上,最多存放1页的数据

所以一个节点,最多存放1170个key,1171个指针,而每个指针都指向一个子节点

所以有1171个叶节点,每个叶节点占用1页,也就是,高度为2的树,最多存储1171页的数据

注意,B+Tree非叶子节点是不存储数据的

1页16k,16(k) * 1171(页) = 18736k的数据,因为1行1k的数据,也就是18736行

当高度为3:高度为2时,1171个叶节点,而每个叶节点可以存放1171个指针,

所以 1171 * 1171 * 16 约等于 2200万 条记录

也就是2200万条记录,InnoDB存储引擎中,树的高度也才3层

如果数据量再大,还可考虑分库分表

语法

Mysql进阶(上) -- 存储引擎,索引_第44张图片

下面的表需要手动创建,这里是代码

敲了一个小时.....可恨的是没有源码

create database itcast;

use itcast; #注意先打开虚拟机上CentOS

create table tb_user(
    id int primary key auto_increment comment '主键ID',
    name varchar(10) default null comment '姓名',
    phone char(11) default null comment '手机号',
    email varchar(50) check (email like '%@%'), #固定格式...@...
    profession varchar(10),
    age int default null comment '年龄',
    gender char(1) default null comment '1: 男 , 2: 女',
    status tinyint unsigned default '1' comment '状态',
    createtime datetime
) comment '员工表';

insert into tb_user
values (1, '吕布', 17799990000, '[email protected]', '软件工程', 23, '1', 6, '2001-02-02 00:00:00'),
       (2, '曹操', 17799990001, '[email protected]', '通讯工程', 33, '1', 0, '2001-03-05 00:00:00'),
       (3, '赵云', 17799990002, '[email protected]', '英语', 34, '1', 2, '2002-03-02 00:00:00'),
       (4, '孙悟空', 17799990003, '[email protected]', '工程造价', 54, '1', 0, '2001-07-02 00:00:00'),
       (5, '花木兰', 17799990004, '[email protected]', '软件工程', 23, '2', 1, '2001-04-22 00:00:00'),
       (6, '大乔', 17799990005, '[email protected]', '舞蹈', 22, '2', 0, '2001-02-07 00:00:00'),
       (7, '露娜', 17799990006, '[email protected]', '应用数学', 24, '2', 0, '2001-08-02 00:00:00'),
       (8, '程咬金', 17799990007, '[email protected]', '化工', 38, '1', 5, '2001-05-23 00:00:00'),
       (9, '项羽', 17799990008, '[email protected]', '金属材料', 43, '1', 0, '2001-09-18 00:00:00'),
       (10, '白起', 17799990009, '[email protected]', '机械工程及其自动化', 27, '1', 2, '2001-08-16 00:00:00'),
       (11, '韩信', 17799990010, '[email protected]', '无机非金属材料工程', 27, '1', 0, '2001-06-12 00:00:00'),
       (12, '荆轲', 17799990011, '[email protected]', '会计', 29, '1', 0, '2001-05-11 00:00:00'),
       (13, '兰陵王', 17799990012, '[email protected]', '工程造价', 44, '1', 1, '2001-04-10 00:00:00'),
       (14, '狂铁', 17799990013, '[email protected]', '应用数学', 43, '1', 2, '2001-02-12 00:00:00'),
       (15, '貂蝉', 17799990014, '[email protected]', '软件工程', 40, '2', 3, '2001-01-30 00:00:00'),
       (16, '妲己', 17799990015, '[email protected]', '软件工程', 31, '2', 0, '2001-05-03 00:00:00'),
       (17, '芈月', 17799990016, '[email protected]', '工业经济', 35, '2', 0, '2000-08-08 00:00:00'),
       (18, '嬴政', 17799990017, '[email protected]', '化工', 38, '1', 1, '2001-03-12 00:00:00'),
       (19, '狄仁杰', 17799990018, '[email protected]', '国际贸易', 30, '1', 0, '2007-08-15 00:00:00'),
       (20, '安琪拉', 17799990019, '[email protected]', '城市规划', 51, '2', 0, '2001-04-12 00:00:00'),
       (21, '典韦', 17799990020, '[email protected]', '城市规划', 52, '1', 2, '2000-07-18 00:00:00'),
       (22, '廉颇', 17799990021, '[email protected]', '土木工程', 19, '1', 3, '2002-08-10 00:00:00'),
       (23, '后裔', 17799990022, '[email protected]', '城市园林', 20, '1', 0, '2002-5-26 00:00:00'),
       (24, '姜子牙', 17799990023, '[email protected]', '工程造价', 29, '1', 4, '2003-02-02 00:00:00');

use itcast;

show index from tb_user;

select * from tb_user;

然后finalshell链接上VMware的CentOS的Linux

在finalshell中输入

mysql -u root -p;

********

use itcast;

show tables;

select * from tb_user;

注意插入后,还需要更新,否则show index后,cardinality显示的一直是0

analyze table tb_user;

Mysql进阶(上) -- 存储引擎,索引_第45张图片

show index from tb_user\G;

create index idx_user_name on tb_user(name);

create unique index idx_user_phone on tb_user(phone);

create index idx_user_pro_age_sta on tb_user(profession,age,status);

create index idx_user_eamil on tb_user(eamil);

drop index idx_user_eamil on tb_user;

Mysql进阶(上) -- 存储引擎,索引_第46张图片

学到这,已经有点懵了,索引是啥? --> 提高数据库查询性能数据结构

性能分析 - 查看执行频次

-->  要做SQL优化,首先得进行SQL性能分析

-->  而SQL优化中,优化的主要部分是select(查询语句)

-->  而优化查询语句时,索引优化占据了主导地位

Mysql进阶(上) -- 存储引擎,索引_第47张图片

global是全局,session是当前会话

Mysql进阶(上) -- 存储引擎,索引_第48张图片
每查询一次,Com_select    | 300,查询次数这里就会多一次,通过这个语句,可以看到当前使用次数最多的是select --> 为后续优化提供依据

性能分析 - 慢查询日志

这一节很麻烦!建议视频和文章一起看!19. 进阶-索引-性能分析-慢查询日志_哔哩哔哩_bilibili

Mysql进阶(上) -- 存储引擎,索引_第49张图片

当Mysql中出现慢查询到的SQL时,就需要我们去优化

一,慢查询配置 

Mysql进阶(上) -- 存储引擎,索引_第50张图片

此时slow_query_log 是关闭的

Mysql进阶(上) -- 存储引擎,索引_第51张图片

这里涉及到Linux的 vi 编辑器

回车,按G切换到末尾,按 i 切换到插入

Mysql进阶(上) -- 存储引擎,索引_第52张图片

注意是输入完 =2后,按"esc"退出插入模式,然后回车

输入 ":x"(Vim编辑器的保存并退出命令),回车

重启

Mysql进阶(上) -- 存储引擎,索引_第53张图片

再次打开左侧标签,再次执行

Mysql进阶(上) -- 存储引擎,索引_第54张图片

二,慢查询查看

我们需要看到这个文件名

Mysql进阶(上) -- 存储引擎,索引_第55张图片

如果没有,输入这个

Mysql进阶(上) -- 存储引擎,索引_第56张图片

可以看到,第3行右边那个value,就是你要 cat 的

Mysql进阶(上) -- 存储引擎,索引_第57张图片

版本8.0.26,端口3306

tail -f 监视MySQL慢查询日志文件的更新,并将新内容输出到终端

Mysql进阶(上) -- 存储引擎,索引_第58张图片

不超过2秒的话,右边root处慢日志查询那里,就不会显示

三,导入1000万数据

下一步,需要从本地导入1000万的数据到Mysql

(1)先建表

CREATE TABLE `tb_sku` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '商品id',
  `sn` varchar(100) NOT NULL COMMENT '商品条码',
  `name` varchar(200) NOT NULL COMMENT 'SKU名称',
  `price` int(20) NOT NULL COMMENT '价格(分)',
  `num` int(10) NOT NULL COMMENT '库存数量',
  `alert_num` int(11) DEFAULT NULL COMMENT '库存预警数量',
  `image` varchar(200) DEFAULT NULL COMMENT '商品图片',
  `images` varchar(2000) DEFAULT NULL COMMENT '商品图片列表',
  `weight` int(11) DEFAULT NULL COMMENT '重量(克)',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  `update_time` datetime DEFAULT NULL COMMENT '更新时间',
  `category_name` varchar(200) DEFAULT NULL COMMENT '类目名称',
  `brand_name` varchar(100) DEFAULT NULL COMMENT '品牌名称',
  `spec` varchar(200) DEFAULT NULL COMMENT '规格',
  `sale_num` int(11) DEFAULT '0' COMMENT '销量',
  `comment_num` int(11) DEFAULT '0' COMMENT '评论数',
  `status` char(1) DEFAULT '1' COMMENT '商品状态 1-正常,2-下架,3-删除',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='商品表';

(2)再插入

Mysql进阶(上) -- 存储引擎,索引_第59张图片

Mysql进阶(上) -- 存储引擎,索引_第60张图片

先把Windows解压后的5个文件上传到Linux

Mysql进阶(上) -- 存储引擎,索引_第61张图片

然后(1条消息) mysql 报错:Loading local data is disabled; this must be enabled on both the client and_loading local data is disabled; this must be enabl_Kane__gao的博客-CSDN博客

Mysql进阶(上) -- 存储引擎,索引_第62张图片回车

输入重启mysql

Mysql进阶(上) -- 存储引擎,索引_第63张图片

然而...还是无法导入....无语了....

按这个再来一下

【数据分析】MySQL之不能导入本地文件“Loading local data is disable;” - 新治 - 博客园 (cnblogs.com)

搞定!成功导入,修改ON后不要重启,直接load语句,但是重启完又会恢复OFF

Mysql进阶(上) -- 存储引擎,索引_第64张图片

但是....

最后200万数据死活插不进去,应该是内存满了

Mysql进阶(上) -- 存储引擎,索引_第65张图片耗时12秒,属于慢查询了

四,再次查询

接下来,再次用 tail -f 慢查询

Mysql进阶(上) -- 存储引擎,索引_第66张图片

成功记录!

那么过一段时间,来看慢查询日志,就知道哪些SQL语句查询效率低,进而优化它

ฅʕ•̫͡•ʔฅ关于[root@192~]mysql>

[root@192~] 是Linux系统中以root用户身份登录到主机时的命令提示符

mysql> 是MySQL数据库命令行客户端的命令提示符

(1)root

执行系统级别的操作和管理任务,如修改系统配置文件、安装软件包等。root用户具有最高的权限,能够对系统进行全面的管理

(2)mysql

通过命令行或终端登录到MySQL服务器时,会看到 mysql> 提示符。在这个提示符下,你可以执行与MySQL相关的命令,如创建数据库、执行查询语句、修改表结构

你可能感兴趣的:(Mysql,mysql,sql,数据库)