• MySql性能优化---分区


    分区介绍

    分区是根据一定的规则,数据库把一个表分解成多个更小的、更容易管理的部分。就访问数据库应用而言,逻辑上就只有一个表或者一个索引,但实际上这个表可能有N个物理分区对象组成,每个分区都是一个独立的对象,可以独立处理,可以作为表的一部分进行处理。分区对应用来说是完全透明的,不影响应用的业务逻辑。

    分区有利于管理非常大的表,它采用分而治之的逻辑,分区引入了分区键的概念,分区键用于根据某个区间值(或者范围值)、特定值列表或者hash函数值执行数据的聚集,让数据根据规则分布在不同的分区中,让一个大对象碧昂城一些小对象。

    MySQL分区即可以对数据进行分区也可以对索引进行分区。

    分区类型

    • range分区:基于一个给定的连续区间范围(区间要求连续并且不能重叠),把数据分配到不同的分区
    • list分区:类似于range分区,区别在于list分区是居于枚举出的值列表分区,range是基于给定的连续区间范围分区
    • hash分区:基于给定的分区个数,把数据分配到不同的分区
    • key分区:类似于hash分区

    注意:无论哪种分区,要么你分区表上没有主键/唯一键,要么分区表的主键/唯一键都必须包含分区键,也就是说不能使用主键/唯一键字段之外的其它字段分区。

    实战

    CREATE TABLE `user` (
       `id` int(11) NOT NULL AUTO_INCREMENT,
       `username` varchar(255) DEFAULT NULL,
       `email` varchar(20) DEFAULT NULL,
       `sex` tinyint(1) DEFAULT NULL,
       `create_time` datetime DEFAULT CURRENT_TIMESTAMP,
       PRIMARY KEY (`id`)
     ) ENGINE=InnoDB AUTO_INCREMENT=5100002 DEFAULT CHARSET=utf8;
    
    

    通过show variables like ‘%datadir%’;命令查看mysql的data存放目录,可以查看是否分区成功。切换到目录中可以看到分区后的表如下

    .....
    user#p#p0.ibd
    user#p#p1.ibd
    user.frm
    ....
    

    在创建分区的时候经常会遇到这个错误:A PRIMARY KEY must include all columns in the table’s partitioning function。意思是说分区的字段必须是要包含在主键当中。解决方法是先把之前的主键删除,再把原来的主键和需要分区的字段都设置为主键。

    ALTER TABLE user DROP PRIMARY KEY, ADD PRIMARY KEY(id, sex);
    

    range分区

    若你是对一个连续区间的范围值进行分区的字段,这个字段满足特定值就分配到该区间,以这样的出发点分区那就用range分区吧。

    在创建表时进行分区:

    -- 语法
    create table <table> (
    	// 字段
    ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1
    partition by range (分区字段) (
      partition <分区名称> values less than (Value),
      partition <分区名称> values less than (Value),
      ...
      partition <分区名称> values less than maxvalue
    );
    
    

    注意:range对应的分区建值必须时数值。

    • range:代表分区方式
    • less than:表示小于
    • Value:表示小于某个具体值,比如 less than (10),那么分区字段的值小于10的分在该分区。

    比如user表中的create_time就是这样的字段。

    create table `user` (
    	// 和上面相同
    ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1
    partition by range (分区字段) (
      partition p0 values less than (1000000),
      partition p1 values less than (2000000),
      partition p2 values less than (3000000),
      partition p3 values less than (4000000),
      partition p5 values less than maxvalue
    );
    

    也可以在创建表之后进行过分区:

    alter table <table> partition by RANGE(id) (
    	PARTITION p0 VALUES LESS THAN (1000000),
        PARTITION p1 VALUES LESS THAN (2000000),
        PARTITION p2 VALUES LESS THAN (3000000),
        PARTITION p3 VALUES LESS THAN (4000000),
        PARTITION p4 VALUES LESS THAN MAXVALUE 
    );
    

    list分区

    若要分区的字段是一个有限值,是固定的,比如枚举类型的。就适合适用list分区。user表中的sex(性别)适合适用list分区

    -- 语法
    create table <table> (
    	// 字段
    ) ENGINE=数据库引擎  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1
    partition by LIST (分区字段或者基于该字段的返回的整数值的表达式) (
      partition <分区名称> values IN (Value1,Value2, Value3),
      ...
      partition <分区名称> values IN (Value4, Value5),
    );
    
    

    如何查看一张表的分区的情况

    Mysql中的SQLyog工具有sql ddl信息,点击查看会出现如下信息:

    /*DDL 信息*/------------
    
    CREATE TABLE `st_address_customer` (
     ...
    ) ENGINE=InnoDB AUTO_INCREMENT=171233 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC COMMENT='审补表'
    /*!50100 PARTITION BY LIST (TASK_TYPE)
    (PARTITION p0 VALUES IN (0) ENGINE = InnoDB,
     PARTITION p1 VALUES IN (1) ENGINE = InnoDB,
     PARTITION p2 VALUES IN (2) ENGINE = InnoDB,
     PARTITION p3 VALUES IN (3,4,5,6,7,8,9) ENGINE = InnoDB) */
    
    

    知道了表的创建语句,表分区的情况不就一目了然了嘛。

    如果想知道表分区存储的数据数目的情况,可以使用下面的语句:

    select partition_name part,partition_expression expr,partition_description descr,table_rows  from INFORMATION_SCHEMA.PARTITIONS where TABLE_SCHEMA=SCHEMA() AND TABLE_NAME='mx_domain'
    

    还有更多的分区形式大家可以看这篇博客,我这篇博客也基本是缩减,照猫画虎。强力推荐一波:

    MySQL性能优化(六):分区

  • 相关阅读:
    这些git技能够你用一年了
    “SSLError: The read operation timed out” when using pip
    Python字符串格式化
    python chardet简单应用
    Python中文字符串截取
    Python time datetime常用时间处理方法
    Python 拷贝对象(深拷贝deepcopy与浅拷贝copy)
    我的Linux随笔目录
    Debian修改ssh端口和禁止root远程登陆设置
    Linux开机启动
  • 原文地址:https://www.cnblogs.com/sean-zeng/p/12465678.html
Copyright © 2020-2023  润新知