type
status
date
slug
summary
tags
category
titleIcon
password
icon
calloutIcon
数字类型
数字类型:整型、浮点、高精度
并发主键
高精度

默认signed

















都是定长
整型计算效率高

页碎片,标记删除,寻找新空间存放,人为表空间碎片整理
存储紧凑 性能更佳


1.MD5十六进制
select hex('a0b1');
select unhex(61306231);
2.ip地址256进制
select inet_aton('192.168.0.1');
select inet_ntoa(3232235521);
3.日期
bigint
On 32-bit platforms, the maximum useful value forunix_timestamp
is 2147483647.999999, which returns'2038-01-19 03:14:07.999999'
UTC. On 64-bit platforms, the effective maximum is 32536771199.999999, which returns'3001-01-18 23:59:59.999999'
UTC. Regardless of platform or version, a greater value forunix_timestamp
than the effective maximum returns0
.
Date and Time Type Storage RequirementsForTIME
,DATETIME
, andTIMESTAMP
columns, the storage required for tables created before MySQL 5.6.4 differs from tables created from 5.6.4 on. This is due to a change in 5.6.4 that permits these types to have a fractional part, which requires from 0 to 3 bytes.
Data Type Storage Required Before MySQL 5.6.4 Storage Required as of MySQL 5.6.4 1 byte 1 byte 3 bytes 3 bytes 3 bytes 3 bytes + fractional seconds storage 8 bytes 5 bytes + fractional seconds storage 4 bytes 4 bytes + fractional seconds storageAs of MySQL 5.6.4, storage forYEAR
andDATE
remains unchanged. However,TIME
,DATETIME
, andTIMESTAMP
are represented differently.DATETIME
is packed more efficiently, requiring 5 rather than 8 bytes for the nonfractional part, and all three parts have a fractional part that requires from 0 to 3 bytes, depending on the fractional seconds precision of stored values.
Fractional Seconds Precision Storage Required 0 0 bytes 1, 2 1 byte 3, 4 2 bytes 5, 6 3 bytesFor example,TIME(0)
,TIME(2)
,TIME(4)
, andTIME(6)
use 3, 4, 5, and 6 bytes, respectively.TIME
andTIME(0)
are equivalent and require the same storage.For details about internal representation of temporal values, see MySQL Internals: Important Algorithms and Structures.
datetime 5位
from_unixtime 只接受到32536771199.999999(35位2进制)的数据转换
Java Instant转换
日期八股

字符串类型:COLLATION

4G
blog无字符集属性







底层多字符字符集 varchar char都是变长

在默认utf8mb4下两个实现一样











enum非sql标准,mysql独有的字符串类型
8.0.16起提供约束功能









可动态盐再合并用户注册日期


密码相同 12345678 存储内容不同
就算拿到密码 加密算法
可以对存储的密码进行升级防范





图片路径 base64
日期类型








daylight saving time










调用操作系统时区 系统调用 上锁 并发问题 ???







订单超时处理
主从数据核对




非结构存储




存储登录信息




JSON表达式
MySQL函数索引索引JSON字段
虚拟列







8.0.17

JSON数组上创建索引









表结构设计-忘记范式






告警 日志 表





36 → 16













订单 后6位相同








表压缩











compress压缩使用性能不敏感业务 日志表 告警表 监控表

存在压缩解压两个页,压缩写入,解压读取(不需要每次都解压)








性能抖动





SQL or NoSQL


















可以结合sql进行复杂的查询,比如结合窗口函数










索引




二叉树 哈希索引 红黑树 skiplist 海量基于磁盘存储数据效率

树矮 插入效率高 排序比较定位快


叶子结点内排序好了,只需二分查找



innoDB 页大小16K




如果查询页缓存在内存缓冲池可以更快



有序:如自增id 时间列 索引插入较快
无序:还存在磁盘随机读写性能不如顺序写影响 比如用户昵称


自增 UUID_TO_BIN 排序UUID




查看未被使用过的b+树索引

数据库运行时间长 索引创建时间久 出现在表格中 可以考虑废弃
MySQL 8.0 在删除索引前可以考虑设置索引对优化器不可见,观察是否对业务有影响



索引组织表
b+树索引基本概念 与 简单管理
mysql innodb存储引擎索引结构

数据存储有堆表(无序存放,数据排序完全依赖于索引)
数据 索引 分开存储 索引是排序后的数据 堆表中的是无序的
索引叶子结点存放了数据在堆表中的地址
当堆表中的数据变化且改变位置,所有索引中的地址都要更新 影响性能

索引组织表 两种方式



innoDB数据是根据主键索引排序存储的,除了主键索引外,其余索引都是二级索引/非聚集索引
二级索引也是b+树索引

不同于主键索引的是叶子结点存放索引主键值


二级索引通过主键索引进行再次查询的设计:如果记录发生修改,其他索引不用维护,除非主键变了
索引组织表在大量变更情况下相比堆表优势明显 大部分情况下都不需要维护二级索引



唯一索引也是二级索引







限制昵称更改频率 提高性能


插入比较顺序 但存在频繁更新操作 对应字段更新导致二级索引修改
因为二级索引需要回表查询,所以设计表结构时让主键值尽可能紧凑,就是为了提高二级索引的性能
16字节顺序UUID

5.7开始







但这时有两份索引 影响性能

虚拟列 由后续表达式计算得到 本身不占据任何存储空间
idx_cellphone实质为函数索引
这样好处是写sql时可以直接使用虚拟列 而不用写冗长的函数

爬虫业务中虚拟列筛选出想要的数据,在虚拟列上创建函数索引对想要的数据快速访问搜索


组合索引


写b=?前也一样

不适用以下sql (a,b)排序不能推出(b,a)排序

可以使用组合索引

不可


根据某个列查询,按照时间方式逆序展示
微博、淘宝订单



额外排序 extra:using filesort




二级索引叶子节点索引键值 主键值

如果查询字段在二级索引的叶子结点中可以直接返回结果避免回表
通过组合索引避免回表的优化→索引覆盖







根据rows估计回表次数






索引出错 CBO


创建索引但使用了全表扫描,问题在索引对应的数据上

优化器选择索引基于成本 CBO cost-based optimizer 分析所有执行计划


CPU:索引键值、记录值比较、结果集排序
IO:8.0可以区分表是否在内存中计算在内存和不在的开销






查询范围不同,索引选择也可能不同


二级索引回表,全表扫描成本低于二级索引



B+树索引需要建立在高选择性的字段上
如订单id 日期等
较少建立在对候选值较少的低选择性字段如性别上
但电商中需要对order_status低选择性字段建立索引

这一字段存在数据倾斜(大部分已完成) 且只查询少量数据

可以对其创建索引

mysql不知道不同值分布,当作平均分布
所以以为全表扫描快于二级索引回表
但由于数据倾斜,事实上会更快

8.0创建直方图 让优化器知道数据分布 从而更好地选择执行计划

创建完后mysql会获得数据分布情况




Join
除了单表设计优化还有多表join与子查询

关联表的数量,查询数据量的多少 OLTP一般左 OLAP右(直接全表效率高)

Nested Loop Join通过索引进行匹配 表R驱动表 通过Where过滤的数据会在S中一一查询
如果驱动表数据量较大 该算法比较高效


INNER JOIN需要查询数量少的表为驱动表

通过索引的效率默认一致,算法会要求驱动表的数量尽可能少







8.0开始支持对OLAP关键的Hash Join算法


海量并发 响应即时

OLTP 若join带有where过滤条件 并且根据主键索引过滤 驱动表只有少量数据 开销小
优化器自行拆分 需要确保索引都已创建


确保使用正确的索引与索引覆盖就可以




12 OLAP
子查询






看执行计划





- 作者:CamelliaV
- 链接:https://camelliav.netlify.app/article/mysql-1
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。