当前位置: 首页 > news >正文

mysql分区技术_高性能的MySQL(7)分区技术

在我之前的2篇博客中已经简单介绍过MySQL5.1之后的分区技术的基本理论和分区技术的表存储文件及特点,博客地址如下:

今天要介绍一下分区技术一些使用场景和机制。

MySQL实现分区表的方式--对底层表封装--意味着索引也按照分区的子表定义的,而没有全局索引。

一、在下面的场景中,作用非常大:

1、表非常大无法全部放到内存中,或者表的最后部分有热点数据,其他均是历史数据。

2、分区的数据更容易维护,可以对整个分区操作,还可以对独立分区进行优化、检查、修复操作。

3、分区表的数据可以分布在不同的物理设备上

4、可以使用分区表来避免某些特殊的瓶颈,例如InnoDB的单个索引互斥访问。

分区表本身也有一些限制:

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

2、分区表达式必须是整数,或者返回整数的表达式。

3、分区表无法使用外键

二、分区表的原理

存储引擎管理分区的各个底层表和管理普通表一样,所有底层表都必须使用相同的引擎,从存储引擎来看,底层表和普通表么有任何不同。

分区表按照下面的操作逻辑进行:

SELECT:

当查询一个分区表的时候,分区层先打开并锁住所有底层表,优化器先判断是否可以过滤掉部分分区,然后进行操作。

INSERT:

当写入一条记录时,分区层先打开并锁住所有的底层表,然后确定哪个分区接收这个记录,操作。

DELETE:

当删除一条记录时,分区层先打开并锁住所有的底层表,然后确定哪个分区接收这个记录,操作。

UPDATE:

当更新一条记录时,分区层先打开并锁住所有的底层表,确定分区,然后取出数据并更新,再判断更新后的数据放到哪个分区,然后进行写入操作,并对原数据所在底层表进行删除。

但并不是每个操作都会锁住所有的表,如果引擎有自己的行级锁,例如InnoDB,则会在分区层释放对应的表锁。

三、如何使用

一般有2个策略:

1、全量扫描数据,不要任何索引。

2、索引数据,并分离热点。

但是必须注意到一下几点:

1、NULL会使分区过滤无效。

第一个分区是一个特殊分区,假设按照PARTITION BY RANGE YEAR(order_date)分区,那么所有order_date为null的或者非法值的,都会被存储到第一个分区。所以这样的查询where order_date between '2012-01-01' and '2012-12-31'会检测2个分区,除了2012这个分区还会检测第一个分区。

为了避免这种情况,可以创建一个无用的第一分区,例如 PARTITION p_null VALUES LESS THAN(0),这样即使检索代价很小的。

2、分区列和索引列不匹配,会导致无法进行分区过滤。

如果a上有索引,而列b进行分区,因为每个分区都有自己独立的索引,所以扫描列b上的索引就需要扫描每一个分区对应的索引。

特别在一个关联查询中,分区表在关联顺序的第二个表,并且索引分区列不匹配,则关联时针对第一个表符合条件的每一个表,都需要访问并搜索第二个表的所有分区。

3、选择分区、打开并锁表,维护分区可能代价很高。

4、所有分区都必须相同的存储引擎。

5、某些引擎不支持分区。

6、分区函数中可以使用的函数和表达式也有一些限制啊。

四、优化查询

使用EXPLAIN PARTITION可以查看优化器是否执行了分区过滤。例如:

41c8a4389f73606b37dcf001b156e233.png

如果我们加一个过滤条件

680cfeda1ec6d2183a45c826711a4a7e.png

但是条件中不能对分区列进行任何表达式和函数操作,那样就无法使用分区过滤例如:

bd89c5baa071d354cace490bc46d49ff.png

我们可以把上面的查询等价的改写一下就可以了。

849a44ea5e8c5956b8b646991bce43e7.png

所以一个重要的原则是创建分区时可以使用表达式,但在查询时只能根据列来过滤分区。

相关文章:

  • mysql7.6.8安装教程_Centos7安装mysql8教程
  • rhel8安装配置mysql_Linux下Mysql8.0.19安装配置图文详解(Redhat centos 6.8)
  • mybatis中 if test 写在select后面_手写一个简易版的Mybatis,带你深入领略它的魅力...
  • anaconda版本与python版本不同_anaconda版本与python关系是什么
  • android 输入法更换_关于Android输入法切换的问题
  • centos gem mysql_CentOS 安装 MySQL
  • 后台怎样获得xmlhttprequest通过post上传的二进制数据_第一阶段,java核心技术开发:Ajax异步XMLHttpRequest对象...
  • 合法的数组定义是_关于运行时异常(Runtime Expection)和自定义异常
  • mysql 图像数据类型_mysql常用的数据类型
  • oracle_sqlserver_mysql_Oracle、SqlServer、MySql临时表总结
  • linux怎么使用mysql存储过程_linux下mysql的操作与存储过程
  • python input函数赋值法_radio赋值法
  • hue sqoop mysql_sqoop2 1.99.5 安装+hue
  • mysql 双向同步表_mysql数据双向同步
  • mysql前端时间转换_前端js日期时间格式转换
  • 网络传输文件的问题
  • JavaScript-如何实现克隆(clone)函数
  • [LeetCode] Wiggle Sort
  • 「面试题」如何实现一个圣杯布局?
  • Iterator 和 for...of 循环
  • Java深入 - 深入理解Java集合
  • Linux各目录及每个目录的详细介绍
  • Redis 懒删除(lazy free)简史
  • vue-cli在webpack的配置文件探究
  • 将回调地狱按在地上摩擦的Promise
  • 力扣(LeetCode)22
  • 面试题:给你个id,去拿到name,多叉树遍历
  • 探索 JS 中的模块化
  • 《码出高效》学习笔记与书中错误记录
  • PostgreSQL之连接数修改
  • ​io --- 处理流的核心工具​
  • #Ubuntu(修改root信息)
  • #Z2294. 打印树的直径
  • (02)vite环境变量配置
  • (04)odoo视图操作
  • (13)[Xamarin.Android] 不同分辨率下的图片使用概论
  • (ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY)讲解
  • (备忘)Java Map 遍历
  • (四)linux文件内容查看
  • (一)u-boot-nand.bin的下载
  • .bat批处理出现中文乱码的情况
  • .gitignore文件—git忽略文件
  • .NET core 自定义过滤器 Filter 实现webapi RestFul 统一接口数据返回格式
  • .NET 编写一个可以异步等待循环中任何一个部分的 Awaiter
  • .NET基础篇——反射的奥妙
  • .NET开源的一个小而快并且功能强大的 Windows 动态桌面软件 - DreamScene2
  • .net实现客户区延伸至至非客户区
  • [Android Studio 权威教程]断点调试和高级调试
  • [C/C++]关于C++11中的std::move和std::forward
  • [HDU3710]Battle over Cities
  • [html] 动态炫彩渐变背景
  • [JavaWeb玩耍日记]Maven的安装与使用
  • [Machine Learning][Part 7]神经网络的基本组成结构
  • [NodeJS]NodeJS基于WebSocket的多用户点对点即时通讯聊天
  • [Oh My C++ Diary]用cout输出时后endl的使用