MySQL表分区

分区原理

  • 根据一定规则将数据库中的一张表分解成多个更小的,容易管理的部分。从逻辑上看只有一张表,但是底层确实由多个物理分区组成。
  • 分区后,表面上还是一张表,但数据散列到多个位置。应用程序读读写的时候操作的还是大表名字,MySQL自动去组织分区的数据。

分区类型

Range分区

mysql> CREATE TABLE range_subarea(id INT, name CHAR(10)) 
    -> PARTITION BY RANGE(id) (
    -> PARTITION p1 VALUES LESS THAN (3),
    -> PARTITION p2 VALUES LESS THAN (5),
    -> PARTITION p3 VALUES LESS THAN (7),
    -> PARTITION p4 VALUES LESS THAN (9),
    -> PARTITION p5 VALUES LESS THAN (11),
    -> PARTITION p6 VALUES LESS THAN MAXVALUE);

插入数据

mysql> INSERT INTO range_subarea VALUES(1, 'aaa'),(2, 'bbb'),(3, 'ccc'),(4, 'ddd'),(5, 'eee'),(6, 'fff'),(7, 'ggg'),(8, 'hhh'),(9, 'iii'),(10, 'jjj');
    -> INSERT INTO range_subarea SELECT * FROM range_subarea;    #反复执行,让数据上千万

我们比较一下拥有同样数据的两张表,一张带分区一张不带分区,查询速度的比较

对比结果显而易见,有分区的表查询速度比没有分区的表查询速度快很多。

我们再来看看SQL的执行计划:

注:我的版本是5.6,在MySQL5.7版以下的版本都需要加PARTITIONS才能看见分区信息

这里可以看出我的执行计划的分区是p3。

List分区

mysql> CREATE TABLE list_subarea(id INT, name CHAR(10)) 
    -> PARTITION BY LIST(id)
    -> (PARTITION p1 VALUES IN (1,3,5,7,9),
    -> PARTITION p2 VALUES IN (2,4,6,8,10));

list分区是指定id进行分区的。

Hash分区

普通hash

mysql> CREATE TABLE hash_subarea(id INT, name CHAR(10)) 
    -> PARTITION BY HASH(id) PARTITIONS 10;

普通hash是就根据id的取模的方式分配数据的。

线性hash

mysql> CREATE TABLE linear_hash_subarea(id INT, name CHAR(10)) 
    -> PARTITION BY LINEAR HASH(id) PARTITIONS 10;

可扩展的hash。

Key分区

mysql> CREATE TABLE key_subarea(id INT, name CHAR(10)) 
-> PARTITION BY LINEAR KEY(id) PARTITIONS 10;

查看表分区

mysql> SELECT partition_name part, 
    -> partition_expression expr, 
    -> partition_description descr, 
    -> table_rows 
    -> FROM INFORMATION_SCHEMA.partitions 
    -> WHERE TABLE_SCHEMA = schema() AND TABLE_NAME='table_name';     

 水平分表与表分区

  水平分表与表分区区别在于前者是将创建多张表分散存放数据,而后者是逻辑上一张表,但是物理上分为个存储文件。这里就水平分表与表分区的优缺点做以概括:

  • 由于表分区是一张逻辑表,表名只有一个,所以数据的查询、排序、分页等等功能不会有分表的问题。
  • 一张逻辑表那么请求的入口只有一个,对读写I/O的压力较大
  • 综上所述,表分区利于读而不利于写
posted @ 2017-12-24 11:47  huanStephen  阅读(260)  评论(0编辑  收藏  举报