`

MySQL分区(mysql partition)

阅读更多

《 http://hi.baidu.com/jackbillow/blog/item/26effe7e637ca0300ed7da66.html》

一、概述

相信有很多人经常会问同样的一个问题:当 MySQL
的总记录数超过了100万后,会出现性能的大幅度下降吗?答案是肯定的,但是性能下降>的比率不一而同,要看系统的架构、应用程序、还有>包括索引、服务器硬件等多种因素而定。当有网友问我这个问题的时候,我最常见的回答>就是:分表,可以根据id区间或者时间先后顺序等多
种规则来分表。分表很容易,然而由此所带来的应用程序甚至是架构方面的改动工作却不>容小觑,还包括将来的扩展性等。

在以前,一种解决方案就是使用 MERGE
类型,这是一个非常方便的做饭。架构和程序基本上不用做改动,不过,它的缺点是显见的:

  • 只能在相同结构的 MyISAM 表上使用
  • 无法享受到 MyISAM 的全部功能,例如无法在 MERGE 类型上执行 FULLTEXT 搜索
  • 它需要使用更多的文件描述符
  • 读取索引更慢

这个时候,MySQL 5.1 中新增的分区(Partition)功能的优势也就很明显了:

  • 与单个磁盘或文件系统分区相比,可以存储更多的数据
  • 很容易就能删除不用或者过时的数据
  • 一些查询可以得到极大的优化
  • 涉及到 SUM()/COUNT() 等聚合函数时,可以并行进行
  • IO吞吐量更大

分区允许可以设置为任意大小的规则,跨文件系统分配单个表的多个部分。实际上,表的不同部分在不同的位置被存储为单独的表。

二、分区的类型

  • RANGE 分区:基于属于一个给定连续区间的列值,把多行分配给分区。参见18.2.1节,RANGE分区
  • LIST 分区:类似于按RANGE分区,区别在于LIST分区是基于列值匹配一个离散值集合中的某个值来进行选择。参见18.2.2节,LIST分区
  • HASH分区:基于用户定义的表达式的返回值来进行选择的分区,该表达式使用将要插入到表中的这些行的列值进行计算。这个函数可以包>含MySQL中有效的、产生非负整数值的任何表达式。参见18.2.3节,HASH分区
  • KEY
    分区:类似于按HASH分区,区别在于KEY分区只支持计算一列或多列,且MySQL服务器提供其自身的哈希函数。必须有一列或多列包含>整数值。
    参见18.2.4节,KEY分区

三、分区例子:

  • RANGE 类型
    CREATE TABLE users (
                             uid INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
                             name VARCHAR(30) NOT NULL DEFAULT '',
                             email VARCHAR(30) NOT NULL DEFAULT ''
                    )
                    PARTITION BY RANGE (uid) (
                             PARTITION p0 VALUES LESS THAN (3000000)
                             DATA DIRECTORY = '/data0/data'
                             INDEX DIRECTORY = '/data1/idx',
                             PARTITION p1 VALUES LESS THAN (6000000)
                             DATA DIRECTORY = '/data2/data'
                             INDEX DIRECTORY = '/data3/idx',
                             PARTITION p2 VALUES LESS THAN (9000000)
                             DATA DIRECTORY = '/data4/data'
                             INDEX DIRECTORY = '/data5/idx',
                             PARTITION p3 VALUES LESS THAN MAXVALUE         DATA DIRECTORY = '/data6/data'
                             INDEX DIRECTORY = '/data7/idx'
                    );

    在这里,将用户表分成4个分区,以每300万条记录为界限,每个分区都有自己独立的数据、索引文件的存放目录,与此同时,这些目录所在的>
    物理磁盘分区可能也都是完全独立的,可以多大提高了磁盘IO吞吐量。

  • LIST 类型
    CREATE TABLE category (
                             cid INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
                             name VARCHAR(30) NOT NULL DEFAULT ''
                    )
                    PARTITION BY LIST (cid) (
                             PARTITION p0 VALUES IN (0,4,8,12)
                             DATA DIRECTORY = '/data0/data'
                             INDEX DIRECTORY = '/data1/idx',
                          
                             PARTITION p1 VALUES IN (1,5,9,13)
                             DATA DIRECTORY = '/data2/data'
                             INDEX DIRECTORY = '/data3/idx',
                          
                             PARTITION p2 VALUES IN (2,6,10,14)
                             DATA DIRECTORY = '/data4/data'
                             INDEX DIRECTORY = '/data5/idx',
                          
                             PARTITION p3 VALUES IN (3,7,11,15)
                             DATA DIRECTORY = '/data6/data'
                             INDEX DIRECTORY = '/data7/idx'
                    );  

    分成4个区,数据文件和索引文件单独存放。

  • HASH 类型
    CREATE TABLE users (
                             uid INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
                             name VARCHAR(30) NOT NULL DEFAULT '',
                             email VARCHAR(30) NOT NULL DEFAULT ''
                    )
                    PARTITION BY HASH (uid) PARTITIONS 4 (
                             PARTITION p0
                             DATA DIRECTORY = '/data0/data'
                             INDEX DIRECTORY = '/data1/idx',
                             PARTITION p1
                             DATA DIRECTORY = '/data2/data'
                             INDEX DIRECTORY = '/data3/idx',
                             PARTITION p2
                             DATA DIRECTORY = '/data4/data'
                             INDEX DIRECTORY = '/data5/idx',
                             PARTITION p3
                             DATA DIRECTORY = '/data6/data'
                             INDEX DIRECTORY = '/data7/idx'
                    );

    分成4个区,数据文件和索引文件单独存放。

  • KEY 类型
    REATE TABLE users (
                             uid INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
                             name VARCHAR(30) NOT NULL DEFAULT '',
                             email VARCHAR(30) NOT NULL DEFAULT ''
                    )
                    PARTITION BY KEY (uid) PARTITIONS 4 (
                             PARTITION p0
                             DATA DIRECTORY = '/data0/data'
                             INDEX DIRECTORY = '/data1/idx',
                          
                             PARTITION p1
                             DATA DIRECTORY = '/data2/data'
                             INDEX DIRECTORY = '/data3/idx',
                          
                             PARTITION p2
                             DATA DIRECTORY = '/data4/data'
                             INDEX DIRECTORY = '/data5/idx',
                          
                             PARTITION p3
                             DATA DIRECTORY = '/data6/data'
                             INDEX DIRECTORY = '/data7/idx'
                    );  

    分成4个区,数据文件和索引文件单独存放。

  • 子分区
    子分区是针对 RANGE/LIST 类型的分区表中每个分区的再次分割。再次分割可以是 HASH/KEY 等类型。例如:

     

    CREATE TABLE users (
                             uid INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
                             name VARCHAR(30) NOT NULL DEFAULT '',
                             email VARCHAR(30) NOT NULL DEFAULT ''
                    )
                    PARTITION BY RANGE (uid) SUBPARTITION BY HASH (uid % 4) SUBPARTITIONS 2(
                             PARTITION p0 VALUES LESS THAN (3000000)
                             DATA DIRECTORY = '/data0/data'
                             INDEX DIRECTORY = '/data1/idx',
                             PARTITION p1 VALUES LESS THAN (6000000)
                             DATA DIRECTORY = '/data2/data'
                             INDEX DIRECTORY = '/data3/idx'
                    );

    对 RANGE 分区再次进行子分区划分,子分区采用 HASH 类型。

    或者

    CREATE TABLE users (
                             uid INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
                             name VARCHAR(30) NOT NULL DEFAULT '',
                             email VARCHAR(30) NOT NULL DEFAULT ''
                    )
                    PARTITION BY RANGE (uid) SUBPARTITION BY KEY(uid) SUBPARTITIONS 2(
                             PARTITION p0 VALUES LESS THAN (3000000)
                             DATA DIRECTORY = '/data0/data'
                             INDEX DIRECTORY = '/data1/idx',
                             PARTITION p1 VALUES LESS THAN (6000000)
                             DATA DIRECTORY = '/data2/data'
                             INDEX DIRECTORY = '/data3/idx'
                    );

    对 RANGE 分区再次进行子分区划分,子分区采用 KEY 类型。

四、分区管理

  • 删除分区
    ALERT TABLE users DROP PARTITION p0;

    删除分区 p0。

  • 重建分区
    • RANGE 分区重建
      ALTER TABLE users REORGANIZE PARTITION p0,p1 INTO (PARTITION p0 VALUES LESS THAN (6000000));

      将原来的 p0,p1 分区合并起来,放到新的 p0 分区中。

    • LIST 分区重建
      ALTER TABLE users REORGANIZE PARTITION p0,p1 INTO (PARTITION p0 VALUES IN(0,1,4,5,8,9,12,13));

      将原来的 p0,p1 分区合并起来,放到新的 p0 分区中。

    • HASH/KEY 分区重建
      ALTER TABLE users REORGANIZE PARTITION COALESCE PARTITION 2;

      用 REORGANIZE 方式重建分区的数量变成2,在这里数量只能减少不能增加。想要增加可以用 ADD PARTITION 方法。

  • 新增分区
    • 新增 RANGE 分区
      ALTER TABLE category ADD PARTITION (PARTITION p4 VALUES IN (16,17,18,19)
                          DATA DIRECTORY = '/data8/data'
                          INDEX DIRECTORY = '/data9/idx');

      新增一个RANGE分区。

    • 新增 HASH/KEY 分区
      ALTER TABLE users ADD PARTITION PARTITIONS 8;

      将分区总数扩展到8个。

    好了,本次体验先到这里,更多详情请看 mysql 手册第18章

分享到:
评论

相关推荐

    MYSQL 通过分区(Partition)提升MySQL性能

    MYSQL 通过分区(Partition)提升MySQL性能,看清楚,不要浪费分数,是MYSQL,不是SQL SERVER2000,有需要的可以下载.

    MySQL分区管理器MySQLPartitionManager.zip

    MySQL Partition Manager 是雅虎开源的 MySQL 分区管理器。它可以帮助你以最小的配置自动创建、维护、清除分区。 标签:MySQL

    创建mysql表分区的方法

    表分区是最近才知道的哦 ,以前自己做都是分表来实现上亿级别的数据了,下面我来给大家介绍一下mysql表分区创建与使用吧,希望对各位同学会有所帮助。表分区的测试使用,主要内容来自于其他博客文章以及mysql5.1的...

    MySql数据分区操作之新增分区操作

    如果想在已经建好的表上进行分区,如果使用alter添加分区的话,mysql会提示错误: 代码如下: ERROR 1505 <HY000> Partition management on a not partitioned table is not possible 正确的方法是新建一个具有分区...

    MySQL交换分区的实例详解

    MySQL交换分区的实例详解 前言 在介绍交换分区之前,我们先了解一下 mysql 分区。 数据库的分区有两种:水平分区和垂直分区。而MySQL暂时不支持垂直分区,因此接下来说的都是水平分区。水平分区即:以行为单位对表...

    详解MySQL分区表

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

    garenchan#my-worklog#06.MySQL分区1

    MySQL分区检查前置条件-- 查看分区插件是否激活 partition -> active-- 查看分区插件是否激活方法2,plugin_status ->

    mysql-分区

    mysql 分区 partition 当进行分区操作,了解对性能所产生的影响是非常有帮助的: 1.创建分区表比无分区的正规表要稍微慢些; 2.通过alter table….drop partition语句进行删除比delete语句要快些; 3.在range或list...

    基于MySQL分区性能的详细介绍

    MySQL从5.1.3开始支持Partition。 分区和手动分表对比 手动分表  分区 多张数据表 一张数据表 重复数据的风险 没有数据重复的风险 写入多张表 写入一张表 没有统一的约束限制 强制的约束限制   MySQL支持...

    MySQL分区表的最佳实践指南

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

    MySQL分区表的局限和限制详解

    禁止构建 分区表达式不支持以下几种构建: 存储过程,存储函数,UDFS或者...在MySQL 5.7.1之前的分区表不支持HANDLER语句,以后的版本取消了这一限制。 服务器SQL模式 如果要用用户自定义分区的表的话,需要注意的是

    MySQL分区表的基本入门教程

    在最近的项目中,我们需要保存大量的数据,而且这些数据是有有效期的,为了提供查询效率以及快速删除过期数据,我们选择了MySQL的分区机制。把数据按照时间进行分区。 分区类型 Range分区:最为常用,基于属于一个...

    Mysql分区表的管理与维护

    改变一个表的分区方案只需使用alter table 加 partition_options 子句就可以了。这篇文章主要介绍了Mysql分区表的管理与维护,非常不错,感兴趣的朋友一起学习吧,需要的朋友可以参考下

    MySQL中表分区技术详细解析

    MySQL 5.1 中新增的分区(Partition)功能就开始增加,优势也越来越明显了: 与单个磁盘或文件系统分区相比,可以存储更多的数据 很容易就能删除不用或者过时的数据 一些查询可以得到极大的优化 涉及到 SUM()/...

    (mysql面试题)MySQL中的分区表的概念及其作用及代码展示.txt

    然后,我们使用`PARTITION BY RANGE`子句对表进行分区,根据`order_date`字段的值将数据划分为四个分区:`p0`、`p1`、`p2`和`p3`。每个分区包含特定年份的数据。 - 最后,我们执行一个查询,筛选出`order_date`大于...

    总结MySQL的分区

    前言  分区是指根据一定的规则将一个...mysql5.7以后查询语句支持指定分区例如:“ SELECT * FROM t PARTITION (p0,p1) WHERE c < 5 ”指定分区同样适用DELETE, INSERT, REPLACE, UPDATE, and LOAD DATA, LOAD XML.

    Mysql数据表分区技术PARTITION浅析

    主要介绍了Mysql数据表分区技术PARTITION浅析,分别介绍了 Mysql 中的分区技术 RANGE、LIST、 HASH,需要的朋友可以参考下

    mysql-partition-and-Index.rar_partition

    mysql表分区的建立,索引的建立,原理说明,还有就是实例的演示

    mysql中如何判断是否支持分区

    mysql可以通过下面语句判断是否支持分区: SHOW VARIABLES LIKE ‘%partition%’; 如果输出: have_partitioning YES 表示支持分区。 或者通过: SHOW PLUGINS; 显示所有插件,如果有partition ACTIVE STORAGE ...

Global site tag (gtag.js) - Google Analytics