深入了解MySQL中分区表的原理与企业级实战

目录
  • 本文导读
  • 一、什么是分区表
  • 二、分区表的工作原理
    • 1、分区表增删改查原理
    • 2、分区表工作原理
  • 三、分区表使用实战
    • 1、分区表企业级实战
    • 2、分区表的使用场景
    • 3、分区表自身限制
    • 4、分区表的误区

本文导读

本文详细讲解什么是分区表,分区表增删改查的工作原理以及分区表的实战,分区表的场景有哪些,哪些场景不建议用分区表,并列举出六点使用分区表的误区。

一、什么是分区表

分区表是一个独立的逻辑表,底层由多个物理子表组成。

分区的代码实际上是底层表的一组处理程序对象的封装。分区表的请求将通过句柄对象(Handler Object)转换为对存储引擎的接口调用。

因此,分区完全封装了SQL层的底层实现,对应用程序是透明的,对SQL层是黑盒的。然而,从底层文件系统的角度来看,很容易发现每个分区表都有一个用#分隔的表文件。

MySQL实现分区表的方式——封装底层表——意味着索引也是根据分区子表定义的,并且没有全局索引。

MySQL在创建表时使用 PARTITION BY 子句定义存储在每个分区中的数据(在第四节详细说明)。

在执行查询时,优化器将根据分区定义筛选没有所需数据的分区。这样,查询不需要扫描所有分区——只需找到包含我们需要的数据的分区。

分区的主要目的之一是以更粗的粒度将数据划分为不同的表。通过这种方式,可以将相关数据存储在一起。此外,可以方便地批量删除整个分区的数据。

二、分区表的工作原理

1、分区表增删改查原理

分区表上的操作遵循以下操作逻辑:

SELECT

查询分区表时,分区层首先打开并锁定所有底层表。优化器首先确定是否可以过滤部分分区,然后调用相应的存储引擎接口来访问每个分区的数据。

INSERT

写入记录时,分区层首先打开并锁定所有底层表,然后确定哪个分区接收记录,然后将记录写入相应的底层表。

DELETE

删除记录时,分区层首先打开并锁定所有底层表,然后确定与数据对应的分区,最后删除相应的底层表。

UPDATE

更新记录时,分区层首先打开并锁定所有底层表。MySQL首先确定要更新的记录的分区,然后取出数据并对其进行更新,然后确定更新后的数据应该放在哪个分区中,最后写入基础表并删除原始数据所在的基础表。

2、分区表工作原理

分区表由多个相关的底层表实现,这些底层表也由处理程序对象表示,因此我们也可以直接访问每个分区。

存储引擎管理分区的所有基础表,就像管理公共表一样(所有基础表必须使用相同的存储引擎)。分区表的索引仅向每个基础表添加相同的索引。

从存储引擎的角度来看,基础表与公共表没有区别,存储引擎不需要知道它是公共表还是分区表的一部分。

尽管每个操作都将”“首先打开并锁定所有基础表”,但这并不意味着分区表将在处理期间锁定整个表。

如果存储引擎可以自己实现行级锁,例如InnoDB,它将在分区层释放相应的表锁。这个锁定和解锁过程类似于普通InnoDB上的查询。

我们在第四节详细说明,使用一些示例来了解在访问分区表时打开和锁定所有基础表的成本和后果。

三、分区表使用实战

1、分区表企业级实战

MySQL支持多个分区表。我们看到的最常见的分区是基于范围的。每个分区存储一个范围内的记录。分区表达式可以是列或包含列的表达式。

例如,下表 按年创建分区表 # 存储在不同的分区中:

CREATE TABLE `***` (
	`ID` BIGINT ( 20 ) NOT NULL AUTO_INCREMENT COMMENT '主键id',
	`LOG_ID` VARCHAR ( 32 ) NOT NULL COMMENT '交易流水号',
	`ODR_ID` VARCHAR ( 32 ) NOT NULL COMMENT '父单号',
	`SUB_ODR_ID` VARCHAR ( 32 ) NOT NULL COMMENT '子单号',
	`CREATE_TIME` datetime ( 0 ) NOT NULL COMMENT '创建时间',
	`CREATE_BY` VARCHAR ( 32 ) NOT NULL COMMENT ' 创建人',
	`UPDATE_TIME` datetime ( 0 ) NOT NULL DEFAULT CURRENT_TIMESTAMP ( 0 ) ON UPDATE CURRENT_TIMESTAMP ( 0 ) COMMENT '更新时间',
	`UPDATE_BY` VARCHAR ( 32 ) NOT NULL COMMENT '更新人',

	PRIMARY KEY ( `ID`, `CREATE_TIME` ) USING BTREE,
	UNIQUE INDEX `UNQ_LOG_SUBODR_ID` ( `LOG_ID`, `SUB_ODR_ID`, `CREATE_TIME` ) USING BTREE,

	INDEX `IDX_ODR_ID` ( `ODR_ID` ) USING BTREE,
	INDEX `IDX_SUB_ID` ( `SUB_ODR_ID` ) USING BTREE,
	INDEX `IDX_CREATE_TIME` ( `CREATE_TIME` ) USING BTREE,
	INDEX `IDX_UPDATE_TIME` ( `UPDATE_TIME` ) USING BTREE
	) ENGINE = INNODB COMMENT = '***业务明细表' 

PARTITION BY RANGE ( YEAR ( `CREATE_TIME` ) ) (
	PARTITION p_2021 VALUES LESS THAN ( 2021 ),
	PARTITION p_2022 VALUES LESS THAN ( 2022 ),
	PARTITION p_2023 VALUES LESS THAN ( 2023 ),
	PARTITION p_2024 VALUES LESS THAN ( 2024 ),
	PARTITION p_catchall VALUES LESS THAN MAXVALUE )  ;

PARTITION分区子句中可以使用各种函数。但是,表达式返回的值必须是一个确定的整数,而不是常数。这里我们使用函数 YEAR() 或任何其他函数。

2、分区表的使用场景

一、表太大,无法存储在内存中,或者只有表的最后一部分有热数据,其余部分是历史数据。

二、分区表数据更易于维护。例如,如果要批量删除大量数据,可以使用清除整个分区的方法。此外,可以优化、检查和修复独立的分区。

三、分区表的数据可以分布在不同的物理设备上,从而可以有效地使用多个硬件设备。

四、分区表可以用来避免一些特殊的瓶颈,例如独占访问InnoDB的单个索引和ext3文件系统的索引节点锁竞争。

五、备份和恢复独立的分区,大的数据集场景。

3、分区表自身限制

一、一个表最多只能有1024个分区。

二、在MySQL 5.1中,分区表达式必须是整数或返回整数的表达式。在MySOL 5.5中在某些情况下,列可以直接用于分区。

三、如果分区字段中有主键列或唯一索引列,则必须包括所有主键列和唯一索引列。

四、分区表中不能使用外键约

4、分区表的误区

4.1 性能提升

许多人会认为分区表将一个大表划分为多个小表,因此MySQL数据库的性能将大大提高。

这是错误的理解!分区表技术并不是用来提高MySQL数据库的性能,而是为了方便数据管理。

分区表的创建需要主键包含分区列;在分区表中唯一索引仅在当前分区文件唯一,而不是全局唯一;分区表唯一索引推荐使用类似 UUID 的全局唯一实现;

分区表不解决性能问题,如果使用非分区列查询,性能反而会更差;推荐分区表用于数据管理、速度快、日志小。

4.2 null值会使分区过滤无效

检查第一个分区,因为 YEAR() 函数在接收非法值时可能返回NULL值,因此该范围的值可能返回NULL并存储在第一个分区中。如果第一个分区非常大,特别是当使用“完全扫描数据,无索引”策略时,成本将非常高。

4.3 分区列和索引列不匹配

如果定义的索引列和分区列不匹配,查询将无法执行分区筛选。

4.4 选择分区的成本可能更高

不同类型的分区以不同的方式实现,因此它们的性能不同。当我们在行中写入大量数据时。每次将一行数据写入范围分区表时,都需要扫描分区定义列表以找到合适的目标分区。

这个问题可以通过限制分区的数量来缓解。根据实际经验,对于大多数系统,大约100个分区没有问题。

4.5 锁住所有表的成本可能更高

当查询和访问分区表时,MySQL需要打开并锁定所有底层表,这是分区表的另一个成本。

单个操作,例如使用批插入或LOAD DATA INFILE一次删除多行数据。

4.6 维护分区的成本可能更高

分区重组的原理类似于ALTER,首先,创建一个临时分区,然后将数据复制到其中,最后删除原始分区。这样会使维护分区的成本可能更高

到此这篇关于深入了解MySQL中分区表的原理与企业级实战的文章就介绍到这了,更多相关MySQL分区表内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • MySQL分区表的正确使用方法

    MySQL分区表概述 我们经常遇到一张表里面保存了上亿甚至过十亿的记录,这些表里面保存了大量的历史记录. 对于这些历史数据的清理是一个非常头疼事情,由于所有的数据都一个普通的表里.所以只能是启用一个或多个带where条件的delete语句去删除(一般where条件是时间). 这对数据库的造成了很大压力.即使我们把这些删除了,但底层的数据文件并没有变小.面对这类问题,最有效的方法就是在使用分区表.最常见的分区方法就是按照时间进行分区. 分区一个最大的优点就是可以非常高效的进行历史数据的清理. 1.

  • 详解MySQL分区表

    前言: 分区是一种表的设计模式,通俗地讲表分区是将一大表,根据条件分割成若干个小表.但是对于应用程序来讲,分区的表和没有分区的表是一样的.换句话来讲,分区对于应用是透明的,只是数据库对于数据的重新整理.本篇文章给大家带来的内容是关于MySQL中分区表的介绍及使用场景,有需要的朋友可以参考一下,希望对你有所帮助. 1.分区的目的及分区类型 MySQL在创建表的时候可以通过使用PARTITION BY子句定义每个分区存放的数据.在执行查询的时候,优化器根据分区定义过滤那些没有我们需要的数据的分区,这

  • MySQL优化之分区表

    当数据库数据量涨到一定数量时,性能就成为我们不能不关注的问题,如何优化呢? 常用的方式不外乎那么几种: 1.分表,即把一个很大的表达数据分到几个表中,这样每个表数据都不多. 优点:提高并发量,减小锁的粒度 缺点:代码维护成本高,相关sql都需要改动 2.分区,所有的数据还在一个表中,但物理存储数据根据一定的规则存放在不同的文件中,文件也可以放到另外磁盘上 优点:代码维护量小,基本不用改动,提高IO吞吐量 缺点:表的并发程度没有增加 3.拆分业务,这个本质还是分表. 优点:长期支持更好 缺点:代码

  • MySQL分区表管理命令汇总

    目录 一.ANALYZE和CHECK PARTITION 分析和检查分区 二.REPAIR 修复分区 三.OPTIMIZE 分区 四.REBUILD分区 五.新增和删除分区 前言: 分区是一种表的设计模式,正确的分区可以极大地提升数据库的查询效率,完成更高质量的SQL编程.但是如果错误地使用分区,那么分区可能带来毁灭性的的结果. 分区功能并不是在存储引擎层完成的,因此不只有InnoDB存储引擎支持分区,常见的存储引擎MyISAM.NDB等都支持分区.但是并不是所有的存储引擎都支持,如CSV.FE

  • MySQL分区表的基本入门教程

    前言 在最近的项目中,我们需要保存大量的数据,而且这些数据是有有效期的,为了提供查询效率以及快速删除过期数据,我们选择了MySQL的分区机制.把数据按照时间进行分区. 分区类型 Range分区:最为常用,基于属于一个给定连续区间的列值,把多行分配给分区.最常见的是基于时间字段. 基于分区的列最好是整型,如果日期型的可以使用函数转换为整型. List分区:LIST分区和RANGE分区类似,区别在于LIST是枚举值列表的集合,RANGE是连续的区间值的集合. Hash分区:基于给定的分区个数,将数据

  • Mysql分区表的管理与维护

    改变一个表的分区方案只需使用alter table 加 partition_options 子句就可以了.和创建分区表时的create table语句很像. 创建表 CREATE TABLE trb3 (id INT, name VARCHAR(50), purchased DATE) PARTITION BY RANGE( YEAR(purchased) ) ( PARTITION p0 VALUES LESS THAN (1990), PARTITION p1 VALUES LESS THA

  • 深入了解MySQL中分区表的原理与企业级实战

    目录 本文导读 一.什么是分区表 二.分区表的工作原理 1.分区表增删改查原理 2.分区表工作原理 三.分区表使用实战 1.分区表企业级实战 2.分区表的使用场景 3.分区表自身限制 4.分区表的误区 本文导读 本文详细讲解什么是分区表,分区表增删改查的工作原理以及分区表的实战,分区表的场景有哪些,哪些场景不建议用分区表,并列举出六点使用分区表的误区. 一.什么是分区表 分区表是一个独立的逻辑表,底层由多个物理子表组成. 分区的代码实际上是底层表的一组处理程序对象的封装.分区表的请求将通过句柄对

  • mysql中的mvcc 原理详解

    目录 简介 前言 一.mysql 数据写入磁盘流程 二.redo log 1.redolog 的整体流程 2.为什么需要 redo log 三.undo log 1.undo log 特点 2.undo log 类型 3.undo log 生成过程 4.undo log 回滚过程 5.undo log的删除 四.mvcc 1.什么是MVCC 2.MVCC组成 3.快照读与当前读 快照读 当前读 五.mvcc操作演示 1.READ COMMITTED 隔离级别 2.REPEATABLE READ 

  • Mysql中事务ACID的实现原理详解

    引言 照例,我们先来一个场景~ 面试官:"知道事务的四大特性么?" 你:"懂,ACID嘛,原子性(Atomicity).一致性(Consistency).隔离性(Isolation).持久性(Durability)!" 面试官:"你们是用mysql数据库吧,能简单说说innodb中怎么实现这四大特性的么?" 你:"我只知道隔离性是怎么做的balabala~~" 面试官:"还是回去等通知吧~" OK,回到正题

  • MySQL中case when对NULL值判断的踩坑记录

    目录 前言 Mysql中case when语法: 案例实战: 总结: 前言 今天在开发程序中,从MySQL中提取数据的时候,使用到了case when的语法用来做判断,在使用过程中在判断NULL值的时候遇到个小问题 sql中的case when 有点类似于Java中的switch语句,比较灵活,但是在Mysql中对于Null的处理有点特殊 Mysql中case when语法: 语法1: CASE case_value WHEN when_value THEN statement_list [WH

  • 详解MySQL中事务隔离级别的实现原理

    前言 说到数据库事务,大家脑子里一定很容易蹦出一堆事务的相关知识,如事务的ACID特性,隔离级别,解决的问题(脏读,不可重复读,幻读)等等,但是可能很少有人真正的清楚事务的这些特性又是怎么实现的,为什么要有四个隔离级别. 今天我们就先来聊聊MySQL中事务的隔离性的实现原理,后续还会继续出文章分析其他特性的实现原理. 当然MySQL博大精深,文章疏漏之处在所难免,欢迎批评指正. 说明 MySQL的事务实现逻辑是位于引擎层的,并且不是所有的引擎都支持事务的,下面的说明都是以InnoDB引擎为基准.

  • 详解MySQL中事务的持久性实现原理

    前言 说到数据库事务,大家脑子里一定很容易蹦出一堆事务的相关知识,如事务的ACID特性,隔离级别,解决的问题(脏读,不可重复读,幻读)等等,但是可能很少有人真正的清楚事务的这些特性又是怎么实现的,为什么要有四个隔离级别. 在之前的文章我们已经了解了MySQL中事务的隔离性的实现原理,今天就继续来聊一聊MySQL持久性的实现原理. 当然MySQL博大精深,文章疏漏之处在所难免,欢迎批评指正. 说明 MySQL的事务实现逻辑是位于引擎层的,并且不是所有的引擎都支持事务的,下面的说明都是以InnoDB

  • MySQL中MVCC机制的实现原理

    目录 前言 什么是当前读和快照读? MVCC的实现原理 前言 MVCC全称为Multi Version Concurrency Control,直译为多版本并发控制,是MySQL中一种并发控制的方法,他主要是为了提高数据库的读写性能,用更好的方式去处理读写冲突. 什么是当前读和快照读? 在讲述MVCC机制实现原理之前,我们先了解一下当前读和快照读 当前读: 其实也很容易理解,当前读指的就是读取的是最新的记录,读取的时候还需要保证其他事务不能修改当前记录,所以会对读取的记录进行加锁处理 例如:se

  • 详解MySQL中Order By排序和filesort排序的原理及实现

    目录 1.Order By原理 2.filesort排序算法 3.优化排序 1.Order By原理 MySQL的Order By操作用于排序,并且会有多种不同的排序算法,他们的性能都是不一样的. 假设有一个表,建表的sql如下: CREATE TABLE `obtest` ( `id` BIGINT NOT NULL AUTO_INCREMENT, `a` VARCHAR ( 100 ) NOT NULL, `b` VARCHAR ( 100 ) NOT NULL, `c` VARCHAR (

  • 深入了解MySQL中索引优化器的工作原理

    目录 本文导读 一.MySQL 优化器是如何选择索引的 1.MySQL数据库组成 2.MySQL数据库成本计算 二.MySQL查询成本 三.SELECT 执行过程 总结 本文导读 本文将解读MySQL数据库查询优化器(CBO)的工作原理.简单介绍了MySQL Server的组成,MySQL优化器选择索引额原理以及SQL成本分析,最后通过 select 查询总结整个查询过程. 一.MySQL 优化器是如何选择索引的 下面我们来看这张表,SUB_ODR_ID字段创建了相关的 2 个索引,根据我们前面

  • MySQL中order by排序语句的原理解析

    order by 是怎么工作的? 表定义 CREATE TABLE `t1` ( `id` int(11) NOT NULL, `city` varchar(16) NOT NULL, `name` varchar(16) NOT NULL, `age` int(11) NOT NULL, `addr` varchar(128) DEFAULT NULL, PRIMARY KEY (`id`), KEY `city` (`city`)) ENGINE=InnoDB; SQL语句可以这样写: se

随机推荐