MySQL高级特性之分区表

对于用户而言,分区表是一个独立的逻辑表,但是在底层由多个物理子表组成。实现分区的代码实际上是对一组底层表的句柄对象的封装,对分区表的请求都会通过句柄对象转化成对存储引擎的接口调用

意义

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

分区的一个主要目的是 将数据按照一个较粗的粒度分别存放在不同的表中。这样做可以将相关的数据存放在一起,另外,当我们想要一次批量删除整个分区的数据也会变得很方便。

在以下的场景中,分区可以起到很大的作用:

  • 表非常大以至于无法全部都放在内存中,或者只在表的最后部分有热点数据其他均是历史数据
  • 分区表的数据更容易维护
  • 分区表的数据可以分布在不同的物理设备上
  • 可以使用分区表来避免某些特殊的瓶颈
  • 如果需要,可以备份和回复独立的分区

分区表本身也有一些限制,下面几点尤为重要:

  • 一张表最多只能有1024个分区
  • 在MySQL5.1 中,分区表达式必须是整数,或者是返回整数的表达式。在MySQL5.5 中,某些场景可以直接使用列来进行分区
  • 分区表中无法使用外键约束
  • 如果分区字段中有主键或者唯一索引的列,那么所有主键列和唯一索引列都必须包含进来

分区表的原理

存储引擎管理分区的各个底层表和管理普通表并没有什么区别(所有的底层表都必须使用相同的存储引擎)
,分区表的索引只是在各个底层表上各自加上一个完全相同的索引。从存储引擎的角度看,底层表和一个普通表并没有什么区别,存储引擎也无需知道这是一个普通表还是一个分区表的一部分。

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

SELECT 查询

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

INSERT 操作

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

DELETE 操作

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

UPDATE 操作

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

这些操作都是支持过滤的。

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

分区表的类型

MySQL支持多种分区表,我们看到最多的就是根据范围进行分区,每个分区存储落在某个范围内的记录。分区表达式可以是列,也可以是包含列的表达式。

例如,如下表就将每一年的销售额都存放在不同的分区中:

CREATE TABLE sales(order_date DATETIME NOT NULL,....
)ENGINE=InnoDB PARTITION BY RANGE(YEAR(order_date))(PARTITION p_2010 VALUES LESS THAN (2010),PARTITION p_2011 VALUES LESS THAN (2011),PARTITION p_2012 VALUES LESS THAN (2012),PARTITION p_catchall VALUES LESS THAN MAXVALUE;
)

PARTITION 分区子句中可以使用各种函数。但是有一个要求, 表达式返回的值必须是一个确定的整数,且不能是一个常数。

MySQL还支持键值、哈希和列表分区等。

如何使用分区表

如果我们希望从一个非常大的表中查询出一段时间的记录,我们应该如何查询这个表,如何才能更加高效?

因为数据量非常大,肯定不能在每次查询的时候都扫描全表,考虑到索引在空间和维护上的消耗,我们也不希望使用索引。即使真的使用索引,也会发现数据并不是按照想要的方式进行聚集,会产生大量的碎片,最终导致一个查询产生成千上万的随机I/O。而事实上,当数据量超级大时,B-Tree索引就已经无法祈祷作用了。

因此我们可以选择一些更粗粒度但消耗更少的方式检索数据,例如在大量的数据上只索引对应的一小块元数据。

这正是分区要做的事情,理解分区可以将其当作索引的最初形态。 因为分区无需额外的数据结构记录每个分区有哪些数据——分区不需要精确定位每条数据的位置,也就无须额外的数据结构——所以其代价非常低。只需要一个简单的表达式就可以表达每个分区存放的是什么数据。

为了保证大数据量的可扩展性,一般有以下两个策略:

  1. 全量扫描数据,不需要任何索引: 只要能够使用 WHERE 条件,将需要的数据限制在少数分区中,则效率是很高的。使用这种策略假设不用将数据完全放入内存中,同时还假设需要的数据全部都在磁盘上。因为内存相对较小,数据很快会被挤出内存,所以缓存起不了任何作用。这个策略适用于以正常的方式访问大量数据的时候。
  2. 索引数据,并分离热点: 如果数据有明显的“热点”,而且除了这部分数据,其他数据很少被访问到,那么可以将这部分热点数据单独放在一个分区中,让这个分区的数据可以有机会都缓存在内存中。这样的查询可以只访问一个很小的分区表,能够使用索引,也能够有效的使用缓存。

什么情况下会出问题

上面介绍的两个分区策略都基于两个非常重要的假设:查询都能够过滤掉很多额外的分区、分区本身并不会带来很多额外的代价。

事实证明,这两个假设在某些场景下会有问题:

  • 分区列和索引列不匹配: 如果定义的索引列和分区列不匹配,会导致可查询无法进行分区过滤。
  • 选择分区的成本可能很高: 不同类型的分区的实现方式也不同,所以它们的性能也各不相同。尤其是范围分区,对于查询符合条件的行在哪些分区的成本可能会非常高,因为服务器需要扫描所有的分区定义的列表来找到正确的答案。
  • 打开并锁住所有底层表的成本可能很高: 当查询访问分区表的时候,MySQL需要打开并锁住所有的底层表,这是分区表的另一个开销。
  • 维护分区的成本可能很高: 某些分区维护操作的速度会非常快,例如新增或者删除分区。而有些操作,比如重组分区或者类似ALTER语句的操作成本可能会很高,因为这类操作需要复制数据。

转载于:https://www.cnblogs.com/AmosH/p/10282314.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/569912.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

关于纯HTML格式写入word

用mht格式生成的word文档不适合批量导出&#xff0c;用纯HTML生成的word文件可以批量导出。我不适用框架直接用localhost本地执行PHP文件的格式如下&#xff1a; <?php header("content-type:text/html;charsetutf-8"); class word{function start(){ob_start()…

判断radio单选按钮是否选中

使用jquery进行判断radio单选是否选中并获取选中的value值。 直接上代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Document</title><script src"https://apps.bdim…

postman上传图片时已经添加cookie,但仍显示未登陆

postman上传图片时&#xff0c;已经添加过cookie&#xff0c;但是返回的结果是用户未登陆&#xff0c;如下图所示&#xff1a; 我的解决办法是&#xff1a;清楚cookie code中的cookie 最终的结果如下&#xff1a;成功 转载于:https://www.cnblogs.com/1510152012huang/p/102825…

关于Oracle数据库导入数据显示中文乱码

一、遇到的问题 问题一&#xff1a;某xxxx.sql文件&#xff0c;里面都是insert语句&#xff0c;并且文本编辑器打开文件查看&#xff0c;里面待插入的中文数据显示正常&#xff0c;但是通过命令行&#xff0c;使用“xxxx.sql”导入数据库后&#xff0c;发现数据库中的中文数据都…

五大主流浏览器及内核

谷歌浏览器&#xff1a;Google Chrome内核&#xff1a;Webkit/blink火狐浏览器&#xff1a;Mozilla Firefox内核&#xff1a;Gecko欧鹏浏览器&#xff1a;opera内核&#xff1a;blink苹果浏览器&#xff1a;Safari内核&#xff1a;WebkitI E 浏 览 器&#xff1a;Windows Inter…

MySQL日期与时间函数

MySQL日期与时间函数 MySQL服务器中的三种时区设置&#xff1a;   ①系统时区—保存在系统变量system_time_zone   ②服务器时区—保存在全局系统变量global.time_zone   ③每个客户端连接的时区—保存在会话变量session.time_zone 注意&#xff1a;   客户端时区…

Docker:单机编排工具docker-compose [十二]

一、docker-compose的安装 1、安装 curl -o /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo yum install -y python2-pip pip install -i https://pypi.tuna.tsinghua.edu.cn/simple docker-compose2、检查是否安装成功 docker-compose -v 二、docke…

MySQL之算术表达式、聚合函数及GROUP BY 与 HANVING 等函数的应用

一、MySQL的算术表达式 算术表达式就是加减乘除的运算过程&#xff0c;主要是对一条数据中出现的数字进行统计和运算。 首先&#xff0c;有一张数据表&#xff0c;如下&#xff1a; mysql> select * from test_score; ------------------------------------------ | id | c…

B1023 组个最小数 (20分)

B1023 组个最小数 &#xff08;20分&#xff09; 给定数字 0-9各若干个。你可以以任意顺序排列这些数字&#xff0c;但必须全部使用。目标是使得最后得到的数尽可能小&#xff08;注意 0 不能做首位&#xff09;。例如&#xff1a;给定两个 0&#xff0c;两个 1&#xff0c;三个…

关于PHP下载文件功能中header()书写方式

一、下载所用header头 header ( "Cache-Control: max-age0" ); header ( "Content-Description: File Transfer" ); header ( Content-disposition: attachment; filename.basename($new_file)); //文件名 header ( "Content-Type: application/png&…

namespace命名空间的使用

一、何为命名空间 PHP 命名空间(namespace)是在PHP 5.3中加入的。“什么是命名空间&#xff1f;从广义上来说&#xff0c;命名空间是一种封装事物的方法。在很多地方都可以见到这种抽象概念。例如&#xff0c;在操作系统中目录用来将相关文件分组&#xff0c;对于目录中的文件…

JS关键字和保留字汇总(小记)

ECMA-262 描述了一组具有特定用途的关键字。这些关键字可用于表示控制语句的开始或结束&#xff0c;或者用于执行特定操作等。按照规则&#xff0c;关键字也是语言保留的&#xff0c;不能用作标识符。以下就是ECMAScript的全部关键字&#xff08;带*号上标的是第5 版新增的关键…

HTML DOM文档对象查找元素的方法

一、HTML DOM 节点 在 HTML DOM (Document Object Model) 中 , 每一个元素都是 节点: 文档是一个文档节点。所有的HTML元素都是元素节点。所有 HTML 属性都是属性节点。文本插入到 HTML 元素是文本节点。注释是注释节点。 二、Document 对象 当浏览器载入 HTML 文档, 它就会…

MySQL的外键约束

一、MySQL外键 外键表示一个表中的一个字段被另一个表中的一个字段引用。外键对相关表中的数据造成了限制&#xff0c;使MySQL的能够保持参照完整性。只有InnoDB类型的表才可以使用外键。    1、外键的好处   可以使得两张表关联&#xff0c;保证数据的一致性和实现一些…

快速排序(C语言)

快速排序 快速排序是一种不稳定排序&#xff0c;它的时间复杂度为O(nlgn)&#xff0c;最坏情况为O(n2)&#xff1b;空间复杂度为O(nlgn)。 这种排序方式是对于冒泡排序的一种改进&#xff0c;它采用分治模式&#xff0c;将一趟排序的数据分割成独立的两部分&#xff0c;其中一…

前端页面-不可编辑控制

1. spring-form 库的使用和不可编辑控制 <form:input path"title" htmlEscape"false" class"form-control required"/> 页面元素不可编辑控制 readOnly“true”&#xff1b; 对input&#xff0c;textArea 有效 disadbled"true";…

js+获取当前域名及跳转、下载操作

一、js获取当前域名 1、方法一 var domain document.domain;2、方法二 var domain window.location.host;3、注意问题   由于获取到的当前域名不包括 http://&#xff0c;所以把获取到的域名赋给 a 标签的 href 时&#xff0c;别忘了加上 http://&#xff0c;否则单击链…

哈希表,哈希算法(C语言)

哈希表 哈希表&#xff0c;又称散列表&#xff0c;常用于在海量数据中查找数据 哈希表中元素是由哈希函数确定的。将数据元素的关键字key作为自变量&#xff0c;通过一定的函数关系H(称为哈希函数)&#xff0c;计算出的值&#xff0c;即为该元素的存储地址。其优点是&#xf…

【OP放大器】在不拆开OP放大器的情况下查一查它是否坏掉或饱和。

用高阻抗的示波器观测工作中的同相电压&#xff0b;点电压即可。 观测虚拟短路的点时&#xff0c;掌握工作中的诸条件&#xff0c;例如电源电压或周围温度的变化、负载的变动、对各种输入信号OP放大器及周边电路是否正常工作等&#xff0c;就可以得到很好的线索。转载于:https:…

Apache配置多个监听端口和访问网站的方法

一个apache服务器的vhost.conf配置文件可以设置Apache监听多个端口&#xff0c;打开Apache的配置文件httpd.conf&#xff0c;在 Listen 80 下面添加多个监听端口如&#xff1a; Listen 8010 Listen 8020 Listen 8030 这样就在vhosts.conf配置文件中增加了8010、8020和8030端…