• 2007-06-22

    MySQL5的分区研究 - [mysql]

    版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
    http://chaochao.blogbus.com/logs/6062945.html

    jimmy | 06 二月, 2007 11:14

    MySQL5.1提供的分区技术,令人对其充满希望。

    根据官方文档,分区技术能够极大的帮助DBA人员。支持的分区模式包括:

    Range

    List

    Hash

    Key

    ----

    安装配置记录:

    wget http://dev.mysql.com/get/Downloads/MySQL-5.1/mysql-5.1.16-beta-linux-i686-icc-glibc23.tar.gz/from/http://mysql.cdpa.nsysu.edu.tw/

    tar -xzvf mysql-5.1.16-beta-linux-i686-icc-glibc23.tar.gz

    mv mysql-5.1.16-beta-linux-i686-icc-glibc23 /usr/local/mysql-5.1

    修改启动脚本,启动

     

    检查当前版本是否支持分区:

    SHOW VARIABLES LIKE '%partition%';

    测试带分区的表:(From 手册)

    CREATE TABLE tr (id INT, name VARCHAR(50), purchased DATE)
    PARTITION BY RANGE(YEAR(purchased))
    (
    PARTITION p0 VALUES LESS THAN (1990),
    PARTITION p1 VALUES LESS THAN (1995),
    PARTITION p2 VALUES LESS THAN (2000),
    PARTITION p3 VALUES LESS THAN (2005)
    );


    INSERT INTO tr VALUES
    (1, 'desk organiser', '2003-10-15'),
    (2, 'CD player', '1993-11-05'),
    (3, 'TV set', '1996-03-10'),
    (4, 'bookcase', '1982-01-10'),
    (5, 'exercise bike', '2004-05-09'),
    (6, 'sofa', '1987-06-05'),
    (7, 'popcorn maker', '2001-11-22'),
    (8, 'aquarium', '1992-08-04'),
    (9, 'study desk', '1984-09-16'),
    (10, 'lava lamp', '1998-12-25');

    从服务器上可以看到文件结构为:

    10.10.82.83 [testuser]$ l
    total 404M
    -rw-rw---- 1 mysql mysql 8.5K 2007-03-14 15:26:29 tr.frm
    -rw-rw---- 1 mysql mysql 32 2007-03-14 15:26:29 tr.par
    -rw-rw---- 1 mysql mysql 68 2007-03-14 15:26:48 tr#P#p0.MYD
    -rw-rw---- 1 mysql mysql 1.0K 2007-03-14 15:26:48 tr#P#p0.MYI
    -rw-rw---- 1 mysql mysql 48 2007-03-14 15:26:48 tr#P#p1.MYD
    -rw-rw---- 1 mysql mysql 1.0K 2007-03-14 15:26:48 tr#P#p1.MYI
    -rw-rw---- 1 mysql mysql 44 2007-03-14 15:26:48 tr#P#p2.MYD
    -rw-rw---- 1 mysql mysql 1.0K 2007-03-14 15:26:48 tr#P#p2.MYI
    -rw-rw---- 1 mysql mysql 84 2007-03-14 15:26:48 tr#P#p3.MYD
    -rw-rw---- 1 mysql mysql 1.0K 2007-03-14 15:26:48 tr#P#p3.MYI

    说明创建分区成功。

    测试分区管理,删除:

    ALTER TABLE tr DROP PARTITION p2;

    添加:

    ALTER TABLE tr ADD PARTITION (PARTITION p2 VALUES LESS THAN (2000));

    注意:

    1,删除分区后,分区内的数据也不可恢复的删除了。

    2,只有range和list分区可以进行无数据影响的添加操作。其他种类的分区,不要进行分区管理。或者是,先把数据全导出,改变分区结构后再导入。

    3,作为分区依据的列值是可以修改的,修改后会转移到对应分区中。(这点很有意义哟~)

    下面是实战:

    CREATE TABLE `user` (
    `id` int(11) not null auto_increment,
    `cn` varchar(22) not null default '',
    `nickname` varchar(32) not null default '',
    `genderid` tinyint(1) unsigned default null,
    `artnum` int(8) unsigned default '0',
    `elitenum` int(8) unsigned default '0',
    `commnum` int(11) not null default '0',
    `delnum` int(8) unsigned default '0',
    `loginnum` int(8) unsigned default '1',
    `linetime` int(8) unsigned default '0',
    `lastdate` datetime default null,
    `power` int(10) not null default '0',
    `score` int(8) default '0',
    `inputdate` datetime default null,
    `finallydate` datetime default null,
    `ad3` tinyint(4) not null default '0',
    primary key (`id`),
    key `nickname` (`nickname`),
    key `finallydate` (`finallydate`)
    ) ENGINE=MyISAM DEFAULT CHARSET=gb2312 AUTO_INCREMENT=4589157
    PARTITION BY RANGE(id)
    (
    PARTITION p5 VALUES LESS THAN (5000000),
    PARTITION p6 VALUES LESS THAN (6000000),
    PARTITION p7 VALUES LESS THAN (7000000),
    PARTITION p8 VALUES LESS THAN (8000000),
    PARTITION p9 VALUES LESS THAN (9000000),
    PARTITION p10 VALUES LESS THAN (10000000),
    PARTITION p11 VALUES LESS THAN (11000000),
    PARTITION p12 VALUES LESS THAN (12000000),
    PARTITION p13 VALUES LESS THAN (13000000),
    PARTITION p14 VALUES LESS THAN (14000000),
    PARTITION p15 VALUES LESS THAN (15000000),
    PARTITION p16 VALUES LESS THAN (16000000),
    PARTITION p0 VALUES LESS THAN MAXVALUE
    );

    关入400万数据,性能对比:

    (待补充)

    方案二,使用Key进行划分

    create table `user2` (
    `cn` varchar(22) not null default '',
    `nickname` varchar(32) not null default '',
    `genderid` tinyint(1) unsigned default null,
    `artnum` int(8) unsigned default '0',
    `elitenum` int(8) unsigned default '0',
    `commnum` int(11) not null default '0',
    `delnum` int(8) unsigned default '0',
    `loginnum` int(8) unsigned default '1',
    `linetime` int(8) unsigned default '0',
    `lastdate` datetime default null,
    `power` int(10) not null default '0',
    `score` int(8) default '0',
    `inputdate` datetime default null,
    `finallydate` datetime default null,
    `ad3` tinyint(4) not null default '0',
    primary key (`cn`),
    key `nickname` (`nickname`),
    key `finallydate` (`finallydate`)
    ) engine=myisam default charset=gb2312
    partition by key(cn)
    partitions 3;

    增加分区数:ALTER TABLE user2 ADD PARTITION PARTITIONS 10;

    减少分区数:ALTER TABLE user2 COALESCE PARTITION 6;

    增加和减少分区时,数据并不丢失。

    一个不很方便的地方在于,当划分分区时,有unique的列时可能会拒绝操作。

    另外,关于性能方面。range,list划分会对提高性能有帮助,但是作用多大,还是跟具体应用有关的。可以肯定的是,不会比我们传统上用程序逻辑将数据分散到多个表的方法效率更高,只是更方便而已。对于hash,key的划分,需要消耗大量计算时间,如果设计不当,可能还会造成性能的下降。所以,这也是我没有立即写性能对比数据的原因。

    以后在实际应用中,采用分区技术确实能够有效提高性能得到验证后,再回来补充性能部分的内容。

    ~~呵呵~~


    历史上的今天:

    mysql的分区 2007-06-22

    收藏到:Del.icio.us