点击上方蓝色“程序猿DD”,选择“设为星标”

回复“资源”获取独家整理的学习资料!

作者 | GrimMjx

来源 | https://www.cnblogs.com/GrimMjx/p/10526821.html

一.InnoDB逻辑存储结构

首先要先介绍一下InnoDB逻辑存储结构和区的概念,它的所有数据都被逻辑地存放在表空间,表空间又由段,区,页组成。

段就是上图的segment区域,常见的段有数据段、索引段、回滚段等,在InnoDB存储引擎中,对段的管理都是由引擎自身所完成的。

区就是上图的extent区域,区是由连续的页组成的空间,无论页的大小怎么变,区的大小默认总是为1MB。

为了保证区中的页的连续性,InnoDB存储引擎一次从磁盘申请4-5个区,InnoDB页的大小默认为16kb,即一个区一共有64(1MB/16kb=16)个连续的页。

每个段开始,先用32页(page)大小的碎片页来存放数据,在使用完这些页之后才是64个连续页的申请。这样做的目的是,对于一些小表或者是undo类的段,可以开始申请较小的空间,节约磁盘开销。

页就是上图的page区域,也可以叫块。页是InnoDB磁盘管理的最小单位。默认大小为16KB,可以通过参数innodb_page_size来设置。

常见的页类型有:数据页,undo页,系统页,事务数据页,插入缓冲位图页,插入缓冲空闲列表页,未压缩的二进制大对象页,压缩的二进制大对象页等。

二.分区概述

分区

这里讲的分区,此“区”非彼“区”,这里讲的分区的意思是指将同一表中不同行的记录分配到不同的物理文件中,几个分区就有几个.idb文件,不是我们刚刚说的区。

MySQL在5.1时添加了对水平分区的支持。分区是将一个表或索引分解成多个更小,更可管理的部分。

每个区都是独立的,可以独立处理,也可以作为一个更大对象的一部分进行处理。这个是MySQL支持的功能,业务代码无需改动。

要知道MySQL是面向OLTP的数据,它不像TIDB等其他DB。那么对于分区的使用应该非常小心,如果不清楚如何使用分区可能会对性能产生负面的影响。

MySQL数据库的分区是局部分区索引,一个分区中既存了数据,又放了索引。也就是说,每个区的聚集索引和非聚集索引都放在各自区的(不同的物理文件)。目前MySQL数据库还不支持全局分区。

无论哪种类型的分区,如果表中存在主键或唯一索引时,分区列必须是唯一索引的一个组成部分。  

三.分区类型

目前MySQL支持以下几种类型的分区,RANGE分区,LIST分区,HASH分区,KEY分区。

如果表存在主键或者唯一索引时,分区列必须是唯一索引的一个组成部分。实战十有八九都是用RANGE分区。

RANGE分区

RANGE分区是实战最常用的一种分区类型,行数据基于属于一个给定的连续区间的列值被放入分区。

但是记住,当插入的数据不在一个分区中定义的值的时候,会抛异常。

RANGE分区主要用于日期列的分区,比如交易表啊,销售表啊等。可以根据年月来存放数据。

如果你分区走的唯一索引中date类型的数据,那么注意了,优化器只能对YEAR(),TO_DAYS(),TO_SECONDS(),UNIX_TIMESTAMP()这类函数进行优化选择。实战中可以用int类型,那么只用存yyyyMM就好了。也不用关心函数了。

CREATE TABLE \`m\_test\_db\`.\`Order\` (  \`id\` INT NOT NULL AUTO_INCREMENT,  \`partition_key\` INT NOT NULL,  \`amt\` DECIMAL(5) NULL,  PRIMARY KEY (\`id\`, \`partition_key\`)) PARTITION BY RANGE(partition_key) PARTITIONS 5( PARTITION part0 VALUES LESS THAN (201901),  PARTITION part1 VALUES LESS THAN (201902),  PARTITION part2 VALUES LESS THAN (201903),  PARTITION part3 VALUES LESS THAN (201904),  PARTITION part4 VALUES LESS THAN (201905)) ;

这时候我们先插入一些数据

INSERT INTO \`m\_test\_db\`.\`Order\` (\`id\`, \`partition_key\`, \`amt\`) VALUES ('1', '201901', '1000');
INSERT INTO \`m\_test\_db\`.\`Order\` (\`id\`, \`partition_key\`, \`amt\`) VALUES ('2', '201902', '800');
INSERT INTO \`m\_test\_db\`.\`Order\` (\`id\`, \`partition_key\`, \`amt\`) VALUES ('3', '201903', '1200');

现在我们查询一下,通过EXPLAIN PARTITION命令发现SQL优化器只需搜对应的区,不会搜索所有分区。关注微信公众号:Java技术栈,在后台回复:MySQL,可以获取我整理的 N 篇最新 MySQL 教程,都是干货。

如果sql语句有问题,那么会走所有区。会很危险。所以分区表后,select语句必须走分区键。

以下3种不是太常用,就一笔带过了。

LIST分区

LIST分区和RANGE分区很相似,只是分区列的值是离散的,不是连续的。LIST分区使用VALUES IN,因为每个分区的值是离散的,因此只能定义值。

HASH分区

说到哈希,那么目的很明显了,将数据均匀的分布到预先定义的各个分区中,保证每个分区的数量大致相同。

KEY分区

KEY分区和HASH分区相似,不同之处在于HASH分区使用用户定义的函数进行分区,KEY分区使用数据库提供的函数进行分区。

四.分区和性能

一项技术,不是用了就一定带来益处。比如显式锁功能比内置锁强大,你没玩好可能导致很不好的情况。

分区也是一样,不是启动了分区数据库就会运行的更快,分区可能会给某些sql语句性能提高,但是分区主要用于数据库高可用性的管理。数据库应用分为2类,一类是OLTP(在线事务处理),一类是OLAP(在线分析处理)。

对于OLAP应用分区的确可以很好的提高查询性能,因为一般分析都需要返回大量的数据,如果按时间分区,比如一个月用户行为等数据,则只需扫描响应的分区即可。在OLTP应用中,分区更加要小心,通常不会获取一张大表的10%的数据,大部分是通过索引返回几条数据即可。

比如一张表1000w数据量,如果一句select语句走辅助索引,但是没有走分区键。那么结果会很尴尬。如果1000w的B+树的高度是3,现在有10个分区。那么不是要(3+3)*10次的逻辑IO?(3次聚集索引,3次辅助索引,10个分区)。所以在OLTP应用中请小心使用分区表。

在日常开发中,如果想查看sql语句的分区查询结果可以使用explain partitions + select sql来获取,partitions标识走了哪几个分区。

mysql> explain partitions select * from TxnList where startTime>'2016-08-25 00:00:00' and startTime<'2016-08-25 23:59:00';
+----+-------------+-------------------+------------+------+---------------+------+---------+------+-------+-------------+
| id | select_type | table             | partitions | type | possible_keys | key  | key_len | ref  | rows  | Extra       |
+----+-------------+-------------------+------------+------+---------------+------+---------+------+-------+-------------+
|  1 | SIMPLE      | ClientActionTrack | p20160825  | ALL  | NULL          | NULL | NULL    | NULL | 33868 | Using where |
+----+-------------+-------------------+------------+------+---------------+------+---------+------+-------+-------------+
row in set (0.00 sec)

参考:《MySQL技术内幕》

往期推荐

聊一聊 Java 服务端中的乱象

震精!Spring Boot内存泄露,排查竟这么难!

每个程序员都必须知道的8种数据结构

Elasticsearch 在互联网公司大量真实的应用案例

6个接私活的网站,你有技术就有钱!

扫一扫,关注我

一起学习,一起进步

一文带你搞懂 MySQL 中的分区!相关推荐

  1. 一文带你搞懂 MySQL 分区!

    一.InnoDB逻辑存储结构 段 区 页 二.分区概述 分区 三.分区类型 RANGE分区 LIST分区 HASH分区 KEY分区 四.分区和性能 一.InnoDB逻辑存储结构 首先要先介绍一下Inn ...

  2. 一文让你搞懂Mysql中 concat函数,ifnull函数,distinct,+号的使用

    数据库的好处: 1:持久化数据到本地 2:可以实现结构化查询,方便管理 数据库相关概念: 1:DB,数据库,保存一组有组织的数据的容器.2:DBMS,数据库管理系统,又称为数据库软件(产品),用于管理 ...

  3. 一文带你搞懂vue中的this.$nextTick

    文章目录 1.Vue.nextTick(callback) 使用原理 2.created和mounted对比 3.例子说明 4.实际遇到的问题:vue项目中 elementUI 中表格多选框默认选中, ...

  4. php算法抽荣耀水晶,还在抱怨王者荣耀水晶难抽?PHP一文带你搞懂游戏中的抽奖算法...

    前言: 没有特别幸运,那么请先特别努力,别因为懒惰而失败,还矫情地将原因归于自己倒霉.你必须特别努力,才能显得毫不费力. 希望:所以说,树倒了,没有一片雪花是无辜的,抽奖都是假的,只有人家想让你中和不 ...

  5. 学习最新大厂付费视频时整理的万字长文+配图带你搞懂 MySQL

    万字长文+配图带你搞懂 MySQL MySQL SQL的介绍 SQL分类 MySQL语法 创建数据库 修改.删除.使用数据库 DDL查询数据表 DDL创建数据表 修改数据表结构 删除数据表 DML添加 ...

  6. 一文带你搞懂从动态代理实现到Spring AOP

    摘要:本文主要讲了Spring Aop动态代理实现的两种方式. 1. Spring AOP Spring是一个轻型容器,Spring整个系列的最最核心的概念当属IoC.AOP.可见AOP是Spring ...

  7. 一文带你搞懂C#多线程的5种写法

    一文带你搞懂C#多线程的5种写法 1.简介 超长警告! 在学习本篇文章前你需要学习的相关知识: 线程基本知识 此篇文章简单总结了C#中主要的多线程实现方法,包括: Thread 线程 ThreadPo ...

  8. 图文结合带你搞懂MySQL日志之Error Log(错误日志)

    GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源. GreatSQL是MySQL的国产分支版本,使用上与MySQL一致. 作者:KAiTO 文章来源:社区原创 往期回顾: 图 ...

  9. RPC框架:一文带你搞懂RPC

    RPC是什么(GPT答) ChatGPT回答: RPC(Remote Procedure Call)是一种分布式应用程序的编程模型,允许程序在不同的计算机上运行.它以一种透明的方式,将一个程序的函数调 ...

最新文章

  1. JavaScript异步编程解决方案探究
  2. r语言 读取dta_R语言将大型Excel文件转为dta格式
  3. 适用于 php-5.2 的 php.ini 中文版
  4. mysql 常用命令(一)
  5. Vue3.0 备受热捧!2020 前端开发进阶必读
  6. 2017.10.11 灾难 失败总结
  7. 电商海报怎么设计,先告诉复古海报要设计要点(附模板)
  8. QString、QByteArray 相互转换、和16进制与asc2转换
  9. 科大讯飞2017年报:营收54亿利润5.9亿,政府补助1.18亿
  10. mdb转换为mysql_如何将MDB(Access)文件转换为MySQL(或纯SQL文件)?
  11. SQL数据库日志文件丢失,日志文件恢复的办法
  12. arcgis 实验教程 第二章 ArcCatalog 简单操作--创建自己独特的工具箱
  13. [OMNET++]ALOHA协议
  14. 5G无线关键技术 — 新型传输波形技术和先进编码与调制技术
  15. 【历史上的今天】1 月 6 日:“互联网之子”的陨落;微软云服务先驱出生;世界上第一台 5G 笔记本
  16. 电视不正常Android镜像投屏,爱奇艺乐播投屏
  17. Qt官方示例-虚拟键盘使用
  18. 网络舆情数据分析系统技术方案
  19. 2022.03.23绝世武功
  20. Android View的elevation属性,CardView始终在布局顶层覆盖其它控件的解决方式;

热门文章

  1. golang struct 切片数组去重
  2. javascript es6 箭头函数 简介
  3. linux 分区克隆软件 partclone 简介
  4. linux 内核空间与用户空间 简介
  5. linux 文本 查看 搜索
  6. linux 问题 value too large for defined data type 解决方案
  7. python 命令行参数处理 getopt模块详解
  8. docker安装PostgreSQL
  9. golang 打印调用堆栈
  10. 关于Visual Studio 2010与64位系统的问题