首页 > 数据库 >MySQL进阶实战8,分区表详解

MySQL进阶实战8,分区表详解

时间:2022-12-04 15:00:14浏览次数:41  
标签:进阶 分区 查询 索引 分区表 MySQL 数据 底层

一、分区表

分区表是一个独立的逻辑表,底层是由多个物理子表组成。实现分区的代码实际上是对一组底层表的句柄对象的封装。对分区表的请求,都会通过句柄对象转化成对存储引擎的接口调用。每一个分区表都有一个使用#分隔命名的表文件。

MySQL在创建表时使用​​PARTITION BY​​子句定义每个分区存放的数据。在执行查询的时候,优化器会根据分区定义过滤那些我们不需要的数据分区,这样就无须查询所有分区,只需要查找包含需要数据的分区就可以了。

分区的一个主要目的是将数据按照一个较粗的粒度分在不同的表中,这样做就可以将相关的数据存放在一起,另外,如果想一次性删除整个分区的数据也会变得更加简单。

二、分区的作用

  1. 表非常大以至于无法全部放在内存中,或者在表中存在热点数据,也有历史数据;
  2. 分区表的数据更容易维护,想批量删除大量数据时,可以使用清除整个分区的方式,还可以对一个独立的分区进行优化、检查、修复等操作;
  3. 分区表的数据可以分布在不同的物理设备上,从而高效地利用多个硬件设备;
  4. 可以通过分区表来避免某些特殊的瓶颈,比如InnoDB单个索引的互斥访问;
  5. 可以备份和恢复独立的分区;

三、分区的一些限制

  1. 一个表最多只能有1024个分区;
  2. 某些场景中可以直接使用列进行分区;
  3. 分区表中无法使用外键约束;

四、分区表的增删改查

1、select

当查询一个分区表的时候,分区层先打开并锁住所有的底层表,优化器先判断是否可以过滤部分分区,然后再调用对应的存储引擎接口访问各个分区的数据。

2、insert

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

3、delete

当删除一条记录时,分区层先打开并锁住所有的底层表,然后确定数据对应的分区,最后对相应底层表进行删除操作。

4、update

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

虽然每个操作都会“分区层先打开并锁住所有的底层表”,但并不是说分区表的处理过程中是锁住全表的。如果存储引擎能够自己实现行级锁,例如InnoDB,则会在分区层释放对应表锁。这个加锁和解锁过程与普通InnoDB上的查询类似。

五、分区表的类型

MySQL支持多种分区表,分区表达式可以是列,也可以是包含列的表达式,根据时间分区尤为多见。

六、如何使用分区表

假设有一个数据量非常大的表,想从中查询出一段时间的记录,这个表中包含很多年的历史数据,数据是按时间排序的。

因为数据量巨大,肯定不能在每次查询的时候都扫描全表。首先考虑到要使用索引,但此时发现数据并不是按照想要的方式聚集的,而且有大量的碎片,最终会导致一个查询产生成千上万的随机I/O,应用程序随之卡死。

可以有两种方式,对其进行优化。

  1. 让所有的查询都只在数据表上做顺序扫描;
  2. 将数据表和索引全部缓存在内存里;

在数据量超大的时候,B-Tree索引就不好用了,除非是索引覆盖查询,否则数据库服务器需要根据索引扫描的结果回表,查询所有符合条件的记录,如果数据量巨大,还会产生大量随机I/O,查询时间漫长。此外,索引维护的代价也是非常高。此时,可以用分区表来解决,可以通过较小的代价,确定需要的数据在哪个分区表,在此分区表中做顺序扫描,可以建索引,还可以将数据缓存在内存中。

可以通过建立热点分区的方式解决,将热点数据放到一个分区中,让这个分区的数据能够有机会缓存在内存中,这样查询只访问一个很小的分区,能够使用索引,也能够使用缓存,速度快的多。

七、分区表会有哪些问题?

1、分区列和索引列不匹配

如果定义的分区列和索引列不匹配,会导致查询无法进行分区过滤。

假设在列id上定义了索引,在列create_time上进行了分区,因为每个分区都有其独立的索引,所以扫描列create_time上的索引就需要扫描每一个分区内对应的索引。如果每个分区内对应索引的非叶子节点都在内存中,那么扫描的速度还是可以接受的。

2、选择分区的成本可能很高

某一行属于哪个分区?这些符合条件的行在哪个分区?服务器需要扫描所有的分区来找到正确的分区,这样的线性查找的效率并不高,随着分区数的增长,成本会越来越高。

3、打开并锁住所有底层表的成本可能会很高

当查询访问分区表的时候,MySQL需要打开并锁住所有的底层表,这是分区表的一个很大的开销。这个操作在分区过滤之前,所以无法通过分区过滤降低此开销,并且此开销也和分区类型无关,会影响所有的查询。这一点对一些本身查询速度非常快的查询会带来明显的额外开销。可以通过批量操作的方式来降低单个操作的此类开销。

综上所述,分区会有很多隐患和问题。所以目前在进行分区的时候会加入一些限制。

  1. 所有分区都必须使用相同的存储引擎;
  2. 某些存储引擎不支持分区;
  3. 对于MyISAM的分区表,不能使用LOAD INDEX INTO CACHE

八、查询优化

分区最大的优点就是优化器可以根据分区函数来过滤一些分区,通过分区过滤通常可以让查询扫描更少的数据。


标签:进阶,分区,查询,索引,分区表,MySQL,数据,底层
From: https://blog.51cto.com/u_15559285/5909988

相关文章

  • MYSQL高阶语句
    一、SQL高级语句1.1SELECT 显示表格中一个或数个栏位的所有资料 语法:SELECT"栏位"FROM"表名";1.2DISTINCT 不显示重复的资料 语法:SELECTDISTINCT"栏......
  • MySQL主从同步
    1.什么是MySQL主从同步?    “主”指的是MySQL主服务器(master),负责写请求。“从”指的是MySQL从服务器(slave),负责读请求。主从同步指的是将主服务器上的数据同步至从......
  • mysql json操作
     MySQL根据JSON字段的内容检索查询数据使用字段->'$.json属性'进行查询条件使用json_extract函数查询,json_extract(字段,"$.json属性")根据json数组查询,用JSON_CON......
  • mysql授权管理
    1 简介权限系统的作用是授予来自某个主机的某个用户可以查询、更新、删除等数据库操作的权限。通过create user、grant、revoke语句授权权限信息保存在名叫mysql的数......
  • 小练习-把MySQL数据库中的数据存入redis
    #pymysql、json、redis#1、连数据库,查到数据库里面所有的数据,游标类型要用pymysql.curosrs.DictCour#2、查到所有数据[{"id":1,"passwd":"49487dd4f94008a6110275e48a......
  • Angular 复习与进阶系列 – 概念篇
    前言我已经2年没有写Angular,最近又要开始撸了.既然都要复习了,那就干脆也写一个系类当作半教程半深入理解Angular吧.适合阅读的人1.向我一样很长一段时间没有......
  • (一)大白话MySQL执行SQL的流程
    ​​(一)大白话MySQL执行SQL的流程​​​​(二)大白话InnoDB存储引擎的架构设计​​​​(三)大白话MySQLBinlog是什么?​​​​(四)MySQL的BufferPool内存结构​​​​(五)MySQL的Buf......
  • Hive 的分区表的作用,是否越多越好?
    Hive的分区表的作用是啥?越多越好吗?为啥嘞?分区表的作用:  分区表极小的缩小了,数据的查找范围,提高查询速度和性能。越多越好吗:  不是的,原因:  hive如果有过多的......
  • Node访问MySQL出错:Cannot set headers after they are sent to the client
    错误内容解决办法发现代码中出现两个res.send()导致该错误即客户端一次请求但服务端有两个或多个响应导致该错误!......
  • 1.mysql的基本操作、配置
    登录mysql-h主机名-P端口号-u用户名-p密码mysql-hlocalhost-P3306-uroot-pQa123456   退出登录exit或quit  查询所有的库mysql>showdat......