MySQL分区之RANGE分区


环境:
mysql> select version()\G
*************************** 1. row ***************************
version(): 5.5.21-log
1 row in set (0.00 sec)

mysql> SHOW VARIABLES LIKE '%partition%'\G
*************************** 1. row ***************************
Variable_name: have_partitioning
        Value: YES
1 row in set (0.00 sec)

 
主要应用场景:
 
RANGE分区主要用于日期列的分区
 例如历史通话清单表,可以根据年月来分区清单记录
如下是对scpcdr表进行分区
create table scpcdr(
  calltime datetime not null,
  msisdn char(11) not null,
  calltype char(2) not null,
  othercallno char(32) not null,
  calldura integer not null,
  key scpcdridx1(calltime,msisdn)
)engine=innodb
  partition by range(year(calltime)) (
  partition p2013 values less than (2014),
  partition p2014 values less than (2015),
  partition p2015 values less than (2016),
  partition p2016 values less than (2017),
  partition p2017 values less than (2018),
  partition p2018 values less than (2019),
  partition p2019 values less than (2020),
  partition p2020 values less than (2021)
);

SELECT table_schema,table_name,partition_name,
  PARTITION_ORDINAL_POSITION,PARTITION_METHOD,
  PARTITION_EXPRESSION,PARTITION_DESCRIPTION,TABLE_ROWS
  FROM information_schema.PARTITIONS
 WHERE table_name='scpcdr'; 

insert into scpcdr values('2012-10-18 10:12:13','13302117301','01','13089141234',125);
insert into scpcdr values('2013-10-18 10:12:13','13302117302','01','13089141234',125);
insert into scpcdr values('2014-10-18 10:12:13','13302117303','01','13089141234',125);
insert into scpcdr values('2015-10-18 10:12:13','13302117304','01','13089141234',125);
insert into scpcdr values('2016-10-18 10:12:13','13302117305','01','13089141234',125);
insert into scpcdr values('2017-10-18 10:12:13','13302117306','01','13089141234',125);
insert into scpcdr values('2018-10-18 10:12:13','13302117307','01','13089141234',125);
insert into scpcdr values('2019-10-18 10:12:13','13302117308','01','13089141234',125);
insert into scpcdr values('2020-10-18 10:12:13','13302117309','01','13089141234',125);

select * from scpcdr order by calltime;
calltime           msisdn calltype othercallno calldura
2012-10-18 10:12:13 13302117301 01 13089141234 125
2013-10-18 10:12:13 13302117302 01 13089141234 125
2014-10-18 10:12:13 13302117303 01 13089141234 125
2015-10-18 10:12:13 13302117304 01 13089141234 125
2016-10-18 10:12:13 13302117305 01 13089141234 125
2017-10-18 10:12:13 13302117306 01 13089141234 125
2018-10-18 10:12:13 13302117307 01 13089141234 125
2019-10-18 10:12:13 13302117308 01 13089141234 125
2020-10-18 10:12:13 13302117309 01 13089141234 125

便于对scpcdr表管理,如果要删除2013年的数据,我们就不需要执行:
delete from sales where calltime>= '2013-01-01 00:00:00' and date<'2013-12-31 23:59:59'
而只需删除2013年数据所在的分区即可
alter table scpcdr drop partition p2013;  
 

mysql> explain partitions
    -> select * from scpcdr
    -> where (calltime >= '2013-01-01 00:00:00') and (calltime <= '2013-12-31 23:59:59')\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: scpcdr
   partitions: p2013
         type: range
possible_keys: scpcdridx1
          key: scpcdridx1
      key_len: 8
          ref: NULL
         rows: 1
        Extra: Using where
1 row in set (0.00 sec)

这里SQL优化器会只查询P2013分区,提高查询性能 

注意:这里的查询条件里必须明确指出calltime字段,如果用year(calltime)=2013这样的条件,那么还是会遍历所有分区,还有对RANGE分区的查询,优化器只能对year(),to_days(),to_seconds()和unix_timestamp()这类函数进行优化选择
 
mysql> explain partitions select * from scpcdr where year(calltime) = 2013\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: scpcdr
   partitions: p2013,p2014,p2015,p2016,p2017,p2018,p2019,p2020
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 9
        Extra: Using where
1 row in set (0.00 sec)

如果一条记录不属于任何分区会提示出错:
mysql> insert into scpcdr values('2021-10-18 10:12:13','13302117309','01','13089141234',125);
ERROR 1526 (HY000): Table has no partition for value 2021

这时需要新增加分区:
mysql> alter table scpcdr add partition( partition p2021 values less than maxvalue ); 
Query OK, 0 rows affected (0.31 sec)
Records: 0  Duplicates: 0  Warnings: 0

增加分区,分区表达式的值,必须是递增的,不能在已有分区前面插入分区,只能递增新的分区

SELECT table_schema,table_name,partition_name,
PARTITION_ORDINAL_POSITION,PARTITION_METHOD,PARTITION_EXPRESSION,PARTITION_DESCRIPTION,
TABLE_ROWS FROM information_schema.PARTITIONS WHERE table_name='scpcdr'

table_schema table_name partition_name PARTITION_ORDINAL_POSITION PARTITION_METHOD PARTITION_EXPRESSION PARTITION_DESCRIPTION TABLE_ROWS
test scpcdr p2013 1 RANGE year(calltime) 2014 2
test scpcdr p2014 2 RANGE year(calltime) 2015 1
test scpcdr p2015 3 RANGE year(calltime) 2016 1
test scpcdr p2016 4 RANGE year(calltime) 2017 1
test scpcdr p2017 5 RANGE year(calltime) 2018 1
test scpcdr p2018 6 RANGE year(calltime) 2019 1
test scpcdr p2019 7 RANGE year(calltime) 2020 1
test scpcdr p2020 8 RANGE year(calltime) 2021 1
test scpcdr p2021 9 RANGE year(calltime) MAXVALUE 0

mysql> insert into scpcdr values('2021-10-18 10:12:13','13302117309','01','13089141234',125);
Query OK, 1 row affected (0.00 sec)

select *  from scpcdr
 where (calltime >= '2021-10-18 00:00:00') and (calltime <= '2021-10-18 23:59:59');

calltime msisdn calltype othercallno calldura
2021-10-18 10:12:13 13302117309 01 13089141234 125

对RANGE分区的查询,分区表达的选择与查询条件的写法必须相匹配,建议这个最好explain解释查询一下看看查询性能
 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: MySQLRANGE 分区是一种分区类型,允许你根据给定的分区键范围将表分成多个不同的分区。这意味着,你可以指定多个值域,并为每个值域创建一个分区。在插入新行时,MySQL 会根据分区键的值将行存储到适当的分区中。 例如,假设你有一张名为 `sales` 的表,其中包含销售日期和销售额两个列。你可以使用 RANGE 分区将这张表分成几个不同的分区,每个分区包含一个时间段内的销售数据。 下面是一个使用 RANGE 分区的示例: ``` CREATE TABLE sales ( date DATE, amount DECIMAL(10,2) ) PARTITION BY RANGE (YEAR(date)) ( PARTITION p0 VALUES LESS THAN (2000), PARTITION p1 VALUES LESS THAN (2010), PARTITION p2 VALUES LESS THAN (2020), PARTITION p3 VALUES LESS THAN MAXVALUE ); ``` 这条语句会创建一张名为 `sales` 的表,该表被分成 4 个分区,分别对应日期在 2000 年之前、2000 年至 2010 年之间、2010 年至 2020 年之间、2020 年之后的销售数据。 ### 回答2: MySQLRANGE分区是一种在表中按照某个列的范围进行分区的方法。分区是将表中的数据按照一定的规则分割成多个独立的部分,每个部分称为一个分区RANGE分区是根据指定的列的取值范围来进行分区的。 在使用RANGE分区时,我们需要先定义分区函数,指定一个列作为分区键。然后可以根据这个列的范围来划分不同的分区,每个分区可以有自己独立的存储和索引。 例如,我们可以使用RANGE分区将一个订单表按照订单金额的范围进行分区。可以定义分区函数为根据订单金额,范围分为低价订单、中价订单和高价订单三个分区分区函数可以使用多种方式定义,包括使用整型、浮点型、日期型等等。 当我们插入新的订单数据时,系统会根据分区函数将新的数据插入到对应的分区中。这样,相同范围内的订单数据就可以放到同一个分区中,提高数据的查询效率。 同时,RANGE分区也提供了一些其他的灵活选项,如合并相邻的分区、添加新的分区等。这些操作可以帮助我们进行分区的优化和管理。 总的来说,RANGE分区是一种非常有用的MySQL分区方法。通过合理的定义分区函数,将数据按照某一列的取值范围进行划分,可以提高查询效率和管理数据的灵活性。 ### 回答3: MySQLRANGE分区是一种根据某个范围值将表分成多个分区的技术。在RANGE分区中,可以选择一个列作为分区依据,并根据该列的值的范围将表数据分成若干个分区RANGE分区创建需要指定分区键,即用于分区的列。在创建表时,可以使用PARTITION BY RANGE(column)语法来指定分区列。然后,通过指定各个分区的范围值来定义分区。例如,可以使用PARTITION p0 VALUES LESS THAN (100)来定义一个分区范围,表示该分区所包含的数据的分区键值必须小于100。 使用RANGE分区可以实现数据的分布和查询的优化。分区可以根据数据的范围进行划分,使得相同范围的数据在同一个分区中,提高了查询效率。另外,对于某些特定的查询,可以仅对分区内的数据进行扫描,减少了扫描的数据量,进一步提高了查询性能。 RANGE分区还提供了一些管理分区的灵活性。可以通过增加或删除分区来控制数据的增长和存储的使用情况。还可以通过对不同分区采用不同的存储引擎来进一步优化性能。 总之,RANGE分区是一种将表数据按范围划分为多个分区的技术。它提供了优化查询性能、管理数据增长和灵活性等多种好处。在设计和使用数据库时,可以根据实际需求选择是否使用RANGE分区来提高系统的性能和可维护性。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值