MySql调优(二)表分区

一、介绍:

1、概念:表分区,是指根据一定规则,将数据库中的一张表分解成多个更小的,容易管理的部分。从逻辑上看,只有一张表,但是底层却是由多个物理分区组成。mysql数据库中的数据是以文件的形势存在磁盘上的,默认放在/mysql/data下面,通过show variables like '%datadir%';可以查看(也可以通过my.cnf中的datadir来查看),一张表主要对应三个文件:frm存放表结构,myd存放表数据,myi存表索引。如果一张表的数据量太大的话,myd,myi就会很大,查找数据就会很慢。利用mysql的分区功能,在物理上将这一张表对应的三个文件,分割成许多个小块,这样查找数据时,就不用全部查找了,只要知道这条数据在哪一块,然后在那一块找就行了。如果表的数据太大,可能一个磁盘放不下,这时,可以把数据分配到不同的磁盘里面去。

2、表分区与分表的区别:分表与分区的区别在于:分区从逻辑上来讲只有一张表,而分表则是将一张表分解成多张表。

3、表分区的优点:

(1)与单个磁盘或文件系统分区相比,可以存储更多的数据。

(2)对于已经失去保存意义的数据,通常可以通过删除与那些数据有关的分区,很容易地删除那些数据。相反地,在某些情况下,添加新数据的过程又可以通过为那些新数据专门增加一个新的分区,来很方便地实现。

(3)一些查询可以得到极大的优化,这主要是借助于满足一个给定WHERE语句的数据可以只保存在一个或多个分区内,这样在查找时就不用查找其他剩余的分区。因为分区可以在创建了分区表后进行修改,所以在第一次配置分区方案时还不曾这么做时,可以重新组织数据,来提高那些常用查询的效率。

(4)涉及到例如SUM()和COUNT()这样聚合函数的查询,可以很容易地进行并行处理。这种查询的一个简单例子如 “SELECT sale_id, COUNT (orders) as order_total FROM sales GROUP BY sale_id;”。通过“并行”,这意味着该查询可以在每个分区上同时进行,最终结果只需通过总计所有分区得到的结果。

(5)通过跨多个磁盘来分散数据查询,来获得更大的查询吞吐量。

4、分区表的限制因素:

(1)一个表最多只能有1024个分区。

(2) MySQL5.1中,分区表达式必须是整数或者返回整数的表达式。MySQL5.5提供了非整数表达式分区的支持。

(3)如果分区字段中有主键或者唯一索引的列,那么多有主键列和唯一索引列都必须包含进来。即:分区字段要么不包含主键或者索引列,要么包含全部主键和索引列。

(4)分区表中无法使用外键约束。

(5)MySQL的分区适用于一个表的所有数据和索引,不能只对表数据分区而不对索引分区,也不能只对索引分区而不对表分区,也不能只对表的一部分数据分区。

5、判断当前MySQL是否支持分区:show variables like '%partition%';

  have_partintioning 的值为YES,表示支持分区。

6、MySQL支持的分区类型:

(1)RANGE分区:基于属于一个给定连续区间的列值,把多行分配给分区。

(2)LIST分区:类似于按RANGE分区,区别在于LIST分区是基于列值匹配一个离散值集合中的某个值来进行选择。

(3)HASH分区:基于用户定义的表达式的返回值来进行选择的分区,该表达式使用将要插入到表中的这些行的列值进行计算。这个函数可以包含MySQL 中有效的、产生非负整数值的任何表达式。

(4)KEY分区:类似于按HASH分区,区别在于KEY分区只支持计算一列或多列,且MySQL服务器提供其自身的哈希函数。必须有一列或多列包含整数值。

说明:在MySQL5.1版本中,RANGE,LIST,HASH分区要求分区键必须是INT类型,或者通过表达式返回INT类型。但KEY分区的时候,可以使用其他类型的列(BLOB,TEXT类型除外)作为分区键。

二、RANGE分区:根据范围分区,范围应该连续但是不重叠,使用PARTITION BY RANGEVALUES LESS THAN关键字。不使用COLUMNS关键字时RANGE括号内必须为整数字段名或返回确定整数的函数。

1、语法:

(1)根据数值范围:

drop table if exists test;
CREATE TABLE `test` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_name` varchar(255) DEFAULT NULL COMMENT '名称',
  `user_age` int(11) DEFAULT NULL COMMENT '年龄',
  `birthday` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=myisam   DEFAULT CHARSET=utf8mb4
partition by range(id)(
    partition p0 values less than (10),
    partition p1 values less than (20),
    partition p2 values less than (30),
    partition p3 values less than (40),
    partition p4 values less than MAXVALUE 
);

注意最后一句没有的话插入id>40的数据会报错。看下生成的文件:

测试:插入几条数据,可以看到分别插入了p0和p4分区。

insert into test(user_name) VALUES('测试1');
insert into test(id,user_name) VALUES(50,'测试50');

(2)根据TIMESTAMP范围:

drop table if exists test;
CREATE TABLE `test` (
  `id` int(11) NOT NULL ,
  `user_name` varchar(255) DEFAULT NULL COMMENT '名称',
  `user_age` int(11) DEFAULT NULL COMMENT '年龄',
  `birthday` timestamp not null default current_timestamp on update current_timestamp
) ENGINE=myisam   DEFAULT CHARSET=utf8mb4
partition by range(unix_timestamp(birthday))(
  partition p0 values less than (unix_timestamp('2000-01-01 00:00:00')),
  partition p1 values less than (unix_timestamp('2010-04-01 00:00:00')),
  partition p2 values less than maxvalue
);

(3)根据DATEDATETIME范围:添加COLUMNS关键字可定义非integer范围及多列范围,不过需要注意COLUMNS括号内只能是列名,不支持函数;多列范围时,多列范围必须呈递增趋势:

drop table if exists test;
CREATE TABLE `test` (
  `id` int(11) NOT NULL ,
  `user_name` varchar(255) DEFAULT NULL COMMENT '名称',
  `user_age` int(11) DEFAULT NULL COMMENT '年龄',
  `birthday` date not null
) ENGINE=myisam   DEFAULT CHARSET=utf8mb4
partition by range columns(birthday)(
  partition p0 values less than ('2000-01-01'),
  partition p1 values less than ('2020-01-01'),
  partition p2 values less than maxvalue
);

(4)根据多列范围:

drop table if exists test;
CREATE TABLE `test` (
  `id` int(11) NOT NULL ,
  `user_name` varchar(255) DEFAULT NULL COMMENT '名称',
  `user_age` int(11) DEFAULT NULL COMMENT '年龄',
  `birthday` date not null
) ENGINE=myisam   DEFAULT CHARSET=utf8mb4
partition by range columns(id,user_age)(
  partition p0 values less than (0,10),
  partition p1 values less than (10,20),
  partition p2 values less than (20,30),
  partition p3 values less than (30,40),
  partition p4 values less than (40,50),
  partition p5 values less than (maxvalue,maxvalue)
);

2、RANGE分区在如下场合特别有用:

(1)当需要删除一个分区上的数据时,只删除分区即可。如使用”alter table test drop partition p0;”,比运行”delete from test  where...”有效得多;

(2)想要使用一个包含有日期或时间值,或包含有从一些其他级数开始增长的值的列;

(3)经常运行直接依赖于用于分割表的列的查询。如执行”select count(*) from test where year(birthday) = 2020 ”,MySQL可以很迅速地确定只有分区p1需要扫描,这是因为余下的分区不可能包含有符合该WHERE子句的任何记录。

三、LIST分区:根据具体数值分区,每个分区数值不重叠,使用PARTITION BY LISTVALUES IN关键字。跟Range分区类似,不使用COLUMNS关键字时List括号内必须为整数字段名或返回确定整数的函数。类似于按RANGE分区,区别在于LIST分区是基于列值匹配一个离散值集合中的某个值来进行选择。如果试图插入列值(或分区表达式的返回值)不在分区值列表中的一行时,那么“INSERT”查询将失败并报错。与Range分区相同,添加COLUMNS关键字可支持非整数和多列。

1、语法:

drop table if exists test;
CREATE TABLE `test` (
  `id` int(11) NOT NULL ,
  `user_name` varchar(255) DEFAULT NULL COMMENT '名称',
  `user_age` int(11) DEFAULT NULL COMMENT '年龄',
  `birthday` date not null
) ENGINE=Innodb   DEFAULT CHARSET=utf8mb4
partition by list(user_age)(
  partition p0 values in (2,4,6,8,10),
  partition p1 values in (1,3,5,7,9)
);


四、Hash分区:主要用来确保数据在预先确定数目的分区中平均分布,Hash括号内只能是整数列或返回确定整数的函数,实际上就是使用返回的整数对分区数取模。要使用HASH分区来分割一个表,要在CREATE TABLE 语句上添加一个“PARTITION BY HASH (expr)”子句,其中“expr”是一个返回一个整数的表达式。它可以仅仅是字段类型为MySQL整型的一列的名字。此外,你很可能需要在后面再添加一个“PARTITIONS num”子句,其中num是一个非负的整数,它表示表将要被分割成分区的数量。如果没有包括一个PARTITIONS子句,那么分区的数量将默认为1。

1、语法:

drop table if exists test;
CREATE TABLE `test` (
  `id` int(11) NOT NULL ,
  `user_name` varchar(255) DEFAULT NULL COMMENT '名称',
  `user_age` int(11) DEFAULT NULL COMMENT '年龄',
  `birthday` date not null
) ENGINE=Innodb   DEFAULT CHARSET=utf8mb4
partition by hash(id)
partitions 4;


drop table if exists test;
CREATE TABLE `test` (
  `id` int(11) NOT NULL ,
  `user_name` varchar(255) DEFAULT NULL COMMENT '名称',
  `user_age` int(11) DEFAULT NULL COMMENT '年龄',
  `birthday` date not null
) ENGINE=Innodb   DEFAULT CHARSET=utf8mb4
partition by hash(year(birthday))
partitions 4;


Hash分区也存在与传统Hash分表一样的问题,可扩展性差。MySQL也提供了一个类似于一致Hash的分区方法-线性Hash分区,只需要在定义分区时添加LINEAR关键字。线性哈希功能,它与常规哈希的区别在于,线性哈希功能使用的一个线性的2的幂(powers-of-two)运算法则,而常规哈希使用的是求哈希函数值的模数。

drop table if exists test;
CREATE TABLE `test` (
  `id` int(11) NOT NULL ,
  `user_name` varchar(255) DEFAULT NULL COMMENT '名称',
  `user_age` int(11) DEFAULT NULL COMMENT '年龄',
  `birthday` date not null
) ENGINE=Innodb   DEFAULT CHARSET=utf8mb4
partition by linear hash(year(birthday))
partitions 4;


五、KEY分区:Key分区与Hash分区很相似,只是Hash函数不同,定义时把Hash关键字替换成Key即可,同样Key分区也有对应与线性Hash的线性Key分区方法。在KEY分区中使用关键字LINEAR和在HASH分区中使用具有同样的作用,分区的编号是通过2的幂(powers-of-two)算法得到,而不是通过模数算法。另外,当表存在主键或唯一索引时可省略Key括号内的列名,Mysql将按照主键-唯一索引的顺序选择,当找不到唯一索引时报错。

drop table if exists test;
CREATE TABLE `test` (
  `id` int(11) NOT NULL ,
  `user_name` varchar(255) DEFAULT NULL COMMENT '名称',
  `user_age` int(11) DEFAULT NULL COMMENT '年龄',
  `birthday` date not null
) ENGINE=Innodb   DEFAULT CHARSET=utf8mb4
partition by key(id)
partitions 4;


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
mysql管理之道:性能、高可用与监控》由资深mysql专家撰写,以最新的mysql版本为基础,以构建高性能mysql服务器为核心,从故障诊断、设计、sql化、性能参数、mydumper逻辑、xtrabackup热备份与恢复、mysql高可用集群搭建与管理、mysql服务器性能和服务监控等方面多角度深入讲解了如何去管理与维护mysql服务器。 书中内容以实战为导向,所有内容均来自于笔者多年实践经验的总结和对新知识的拓展,同时也针对运维人员、dba等相关工作者会遇到的有代性的疑难问题给出了实用的情景模拟,并给出了解决方案。不论你目前有没有遇到过此类问题,相信对你以后处理相关问题都会有所借鉴。本书适合所有希望构建和管理高性能、高可用性的mysql数据库系统的开发者和dba阅读。 目录 · · · · · · 前言 第一部分 mysql5.5 新特性篇 第1章 mysql5.5介绍 2 1.1 性能上的显著改变 2 1.1.1 mysql5.5默认存储引擎的整 2 1.1.2 充分利用cpu多核的处理能力 7 1.1.3 提高刷新脏页数量和合并插入数量,改善磁盘i/o处理能力 8 1.1.4 增加自适应刷新脏页功能 9 1.1.5 让innodb_buffer_pool缓冲池中的热数据存活更久 9 1.1.6 innodb的数据恢复时间加快 11 1.1.7 innodb同时支持多个bufferpool实例 15 1.1.8 可关闭自适应哈希索引 17 1.1.9 在innodb中可选择使用内存分配程序 18 1.1.10 提高默认innodb线程并发数 21 1.1.11 预读算法的变化 22 1.1.12 首次在linux上实现了异步i/o 23 1.1.13 恢复组提交 24 1.1.14 innodb使用多个回滚段提升性能 26 1.1.15 改善清除程序进度 26 .1.1.16 添加删除缓冲和清除缓冲 27 1.1.17 控制自旋锁spin lock轮训间隔 28 1.1.18 快速创建、删除、更改索引 29 1.1.19 innodb支持创建压缩数据页 30 1.1.20 可动态关闭innodb更新元数据的统计功能 37 1.2 安全性、稳定性的显著改变 38 1.2.1 复制功能加强 38 1.2.2 中继日志relay-log可自我修复 39 1.2.3 开启innodb严格检查模式 39 1.3 动态更改系统配置参数 39 1.3.1 支持动态更改独立空间 39 1.3.2 支持动态更改innodb锁超时时间 40 1.4 innodb新参数汇总 40 1.5 同步复制新参数汇总 48 1.6 sql语句写法的改变 53 1.6.1 delete连接语法改变 53 1.6.2 mysql5.5存储过程支持limit变量 54 1.7 mysql5.1升级为mysql5.5 55 1.7.1 采用mysql_upgrade升级授权方式升级 55 1.7.2 直接安装mysql5.5,采用数据导出/导入方式升级 59 1.8 性能测试:mysql5.5与mysql5.1 60 第2章 半同步复制 62 2.1 半同步复制简介 62 2.2 半同步复制安装配置 63 2.3 参数说明 63 2.4 功能测试 64 2.4.1 如何验证半同步复制是否正常工作 64 2.4.2 半同步复制与异步复制的切换 65 2.5 性能测试 68 2.6 小结 70 第二部分 故障诊断与性能化篇 第3章 故障诊断 72 3.1 影响mysql性能的因素 72 3.2 系统性能评估标准 73 3.2.1 影响linux服务器性能的因素 73 3.2.2 系统性能评估指标 74 3.2.3 开源监控和评估工具介绍 76 3.3 故障与处理 79 3.3.1 连接数过多导致程序连接报错的原因 79 3.3.2 记录子查询引起的宕机 84 3.3.3 诊断事务量突高的原因 87 3.3.4 谨慎设置binlog_format=mixed 90 3.3.5 未设置swap分区导致内存耗尽,主机死机 94 3.3.6 mysql故障切换之事件度器注意事项 95 3.3.7 人工误删除innodb ibdata数据文件,如何恢复 97 3.3.8 update忘加where条件误操作恢复(模拟oracle闪回功能) 99 3.3.9 delete忘加where条件误操作恢复(模拟oracle闪回功能) 108 第4章 同步复制报错故障处理 112 4.1 最常见的3种故障 112 4.1.1 在master上删除一条记录时出现的故障 112 4.1.2 主键重复 114 4.1.3 在master上更新一条记录,而slave上却找不到 115 4.2 特殊情况:slave的中继日志relay-log损坏 116 4.3 人为失误 118 4.4 避免在master上执行大事务 119 4.5 slave_exec_mode参数可自动处理同步复制错误 120 4.6 如何验证主从数据一致 121 4.7 binlog_ignore_db引起的同步复制故障 123 4.8 mysql5.5.19/20同步一个bug 124 4.9 恢复slave从机上的某几张的简要方法  126 4.10 如何干净地清除slave同步信息 127 第5章 性能 129 5.1 设计 129 5.2 字段类型的选取 133 5.2.1 数值类型 134 5.2.2 字符类型 139 5.2.3 时间类型 141 5.2.4 小技巧:快速修改结构 148 5.2.5 pt-online-schema-change在线更改结构 152 5.2.6 mysql5.6在线ddl更改测试 158 5.3 采用合适的锁机制 161 5.3.1 锁的演示 161 5.3.2 行锁的演示 164 5.3.3 innodb引擎与myisam引擎的性能对比 166 5.4 选择合适的事务隔离级别 168 5.4.1 事务的概念 168 5.4.2 事务的实现 169 5.4.3 事务隔离级别介绍 171 5.5 sql化与合理利用索引 177 5.5.1 如何定位执行很慢的sql语句 177 5.5.2 sql化案例分析 178 5.5.3 合理使用索引 188 5.6 my.cnf配置文件 198 5.6.1 per_thread_buffers化 198 5.6.2 global_buffers化 200 5.6.3 query cache在不同环境下的使用 201 5.6.4 tuning-primer.sh性能试工具的使用 205 5.6.5 72 gb内存的my.cnf配置文件 208 5.6.6 谨慎使用分区功能 211 5.7 mysql5.6同步复制新特性详解 213 第6章 备份与恢复 223 6.1 冷备份 224 6.2 逻辑备份 224 6.2.1 mysqldump增加了一个重要参数 225 6.2.2 取代mysqldump的新工具mydumper 226 6.2.3 逻辑备份全量、增量备份脚本 229 6.3 热备份与恢复 230 第三部分 高可用集群管理篇 第7章 目前流行的4种高可用架构 236 7.1 采用mysql自带的replication架构 237 7.1.1 keepalived+mysql replication架构的搭建演示 237 7.1.2 mmm+mysql replication架构的搭建演示 241 7.2 heartbeat+drbd+mysql架构的搭建演示 249 7.3 红帽rhcs共享存储架构的搭建演示 254 7.3.1 安装过程 257 7.3.2 红帽rhcs集群的维护 265 7.4 mysql高可用集群ha解决方案的测试评估 267 第8章 批量管理服务器 270 8.1 开源工具pssh的使用方法 270 8.2 自己编写的ssh服务器批量管理工具 273 第四部分 监控篇 第9章 性能监控 278 第10章 服务监控 283 10.1 nagios搭建与维护 283 10.2 mysql数据库的监控脚本 288 第五部分 项目案例 第11章 项目案例讲解 292 11.1 数据碎片整理方案 292 11.2 用户信息水平拆方案 296 11.3 阿里巴巴中间件cobar水平拆方案 299
当涉及到MySQL数据库时,有几个关键的方面需要考虑。以下是一些常见的MySQL方法: 1. 化查询语句:化查询语句是提高MySQL性能的首要步骤。使用合适的索引,避免全扫描;避免使用SELECT *,只选择需要的列;避免使用子查询,可以改写为JOIN操作等。 2. 适当整缓冲区:MySQL使用多个缓冲区来提高性能,包括查询缓存、缓存和InnoDB缓冲池。根据数据库的大小和服务器的可用内存,适当整这些缓冲区的大小。 3. 配置合理的连接池:MySQL默认使用单线程处理连接,可以通过配置连接池来提高并发性能。适当增加最大连接数、整连接超时时间等。 4. 结构:根据数据访问模式对进行规范化或去规范化,使用正确的数据类型和字段长度,避免使用过多的索引等。 5. 分区:对于大型,可以考虑使用分区来提高查询性能。分区可以根据时间、地理位置等进行划分。 6. 整日志和参数设置:根据具体需求整日志设置和参数配置,如错误日志、慢查询日志、binlog日志的开启与关闭,以及innodb_buffer_pool_size、innodb_log_file_size等参数的整。 7. 监控和化查询计划:使用MySQL自带的性能监控工具或第三方工具来监控查询执行计划,找出慢查询和瓶颈,并进行化。 8. 定期维护和化:定期进行数据库维护操作,如化、索引重建、统计信息更新等,以保持数据库的良好性能。 以上是一些常见的MySQL方法,具体的化策略需要根据实际情况进行评估和实施。在进行任何操作之前,最好备份数据库以防止意外情况发生。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

w_t_y_y

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值