mysql 分区 range,MySQL分区之RANGE分区

环境:

mysql> select version()\G;

*************************** 1. row ***************************

version(): 5.5.28

㈠ 主要应用场景

RANGE分区主要用于日期列的分区

例如销售类的表,可以根据年份来分区存储销售记录

如下是对sales表进行分区

mysql> create table sales(money int unsigned not null,

-> date datetime

-> )engine=innodb

-> partition by range (year(date)) (

-> partition p2008 values less than (2009),

-> partition p2009 values less than (2010),

-> partition p2010 values less than (2011)

-> );

Query OK, 0 rows affected (0.06 sec)

mysql> insert into sales SELECT 100,\'2008-01-01\';

Query OK, 1 row affected (0.02 sec)

Records: 1 Duplicates: 0 Warnings: 0

mysql> insert into sales SELECT 100,\'2008-02-01\';

Query OK, 1 row affected (0.00 sec)

Records: 1 Duplicates: 0 Warnings: 0

mysql> insert into sales SELECT 200,\'2008-01-02\';

Query OK, 1 row affected (0.00 sec)

Records: 1 Duplicates: 0 Warnings: 0

mysql> insert into sales SELECT 100,\'2008-03-01\';

Query OK, 1 row affected (0.01 sec)

Records: 1 Duplicates: 0 Warnings: 0

mysql> insert into sales SELECT 100,\'2009-03-01\';

Query OK, 1 row affected (0.00 sec)

Records: 1 Duplicates: 0 Warnings: 0

mysql> insert into sales SELECT 200,\'2010-03-01\';

Query OK, 1 row affected (0.00 sec)

Records: 1 Duplicates: 0 Warnings: 0

mysql> select * from sales;

+-------+---------------------+

| money | date |

+-------+---------------------+

| 100 | 2008-01-01 00:00:00 |

| 100 | 2008-02-01 00:00:00 |

| 200 | 2008-01-02 00:00:00 |

| 100 | 2008-03-01 00:00:00 |

| 100 | 2009-03-01 00:00:00 |

| 200 | 2010-03-01 00:00:00 |

+-------+---------------------+

6 rows in set (0.00 sec)

① 便于对sales表管理,如果要删除2008年的数据,我们就不需要执行:

delete from sales where date>= \'2008-01-01\' and date             而只需删除2008年数据所在的分区即可

mysql> alter table sales drop partition p2008;

Query OK, 0 rows affected (0.10 sec)

Records: 0 Duplicates: 0 Warnings: 0

mysql> select * from sales;

+-------+---------------------+

| money | date |

+-------+---------------------+

| 100 | 2009-03-01 00:00:00 |

| 200 | 2010-03-01 00:00:00 |

+-------+---------------------+

2 rows in set (0.00 sec)

② 另一个好处是加快某些查询操作,例如,我们只需要查询2009年整年的销售额

mysql> explain partitions

-> select * from sales

-> where date>=\'2009-01-01\' and date<=\'2009-12-31\'\G;

*************************** 1. row ***************************

id: 1

select_type: SIMPLE

table: sales

partitions: p2009

type: ALL

possible_keys: NULL

key: NULL

key_len: NULL

ref: NULL

rows: 4

Extra: Using where

1 row in set (0.00 sec)

SQL优化器会进行分区修剪,即只搜索p2009

也请注意分区的边界,如date

㈡ 常见相关问题

① 插入了一个不在分区中定义的值

mysql> insert into sales select 200,\'2012-12-3\';

ERROR 1526 (HY000): Table has no partition for value 2012

mysql> show create table sales \G;

*************************** 1. row ***************************

Table: sales

Create Table: CREATE TABLE `sales` (

`money` int(10) unsigned NOT NULL,

`date` datetime DEFAULT NULL

) ENGINE=InnoDB DEFAULT CHARSET=latin1

/*!50100 PARTITION BY RANGE (year(date))

(PARTITION p2009 VALUES LESS THAN (2010) ENGINE = InnoDB,

PARTITION p2010 VALUES LESS THAN (2011) ENGINE = InnoDB) */

1 row in set (0.00 sec)

ERROR:

No query specified

mysql> alter table sales add partition(

-> partition p2012 values less than maxvalue);

Query OK, 0 rows affected (0.04 sec)

Records: 0 Duplicates: 0 Warnings: 0

mysql> insert into sales select 200,\'2012-12-3\';

Query OK, 1 row affected (0.01 sec)

Records: 1 Duplicates: 0 Warnings: 0

mysql> select * from sales where date=\'2012-12-3\';

+-------+---------------------+

| money | date |

+-------+---------------------+

| 200 | 2012-12-03 00:00:00 |

+-------+---------------------+

1 row in set (0.00 sec)

② 对RANGE分区的查询,优化器只能对year(),to_days(),to_seconds()和unix_timestamp()这类函数进行优化选择

mysql> create table t (date datetime)

-> engine=innodb

-> partition by range (year(date)*100+month(date)) (

-> partition p201201 values less than (201202),

-> partition p201202 values less than (201203),

-> partition p201203 values less than (201204)

-> );

Query OK, 0 rows affected (0.02 sec)

mysql> insert into t select \'2012-01-01\';

Query OK, 1 row affected (0.00 sec)

Records: 1 Duplicates: 0 Warnings: 0

mysql> insert into t select \'2012-01-06\';

Query OK, 1 row affected (0.00 sec)

Records: 1 Duplicates: 0 Warnings: 0

mysql> insert into t select \'2012-02-06\';

Query OK, 1 row affected (0.01 sec)

Records: 1 Duplicates: 0 Warnings: 0

mysql> insert into t select \'2012-01-06\';

Query OK, 1 row affected (0.00 sec)

Records: 1 Duplicates: 0 Warnings: 0

mysql> insert into t select \'2012-03-06\';

Query OK, 1 row affected (0.00 sec)

Records: 1 Duplicates: 0 Warnings: 0

mysql> insert into t select \'2012-02-01\';

Query OK, 1 row affected (0.01 sec)

Records: 1 Duplicates: 0 Warnings: 0

mysql> select * from t;

+---------------------+

| date |

+---------------------+

| 2012-01-01 00:00:00 |

| 2012-01-06 00:00:00 |

| 2012-01-06 00:00:00 |

| 2012-02-06 00:00:00 |

| 2012-02-01 00:00:00 |

| 2012-03-06 00:00:00 |

+---------------------+

6 rows in set (0.00 sec)

mysql> explain partitions

-> select * from t

-> where date>=\'2012-01-01\' and date<=\'2012-01-31\'\G;

*************************** 1. row ***************************

id: 1

select_type: SIMPLE

table: t

partitions: p201201,p201202,p201203

type: ALL

possible_keys: NULL

key: NULL

key_len: NULL

ref: NULL

rows: 6

Extra: Using where

1 row in set (0.00 sec)

ERROR:

No query specified

mysql> drop table t;

Query OK, 0 rows affected (0.01 sec)

mysql> create table t (date datetime)

-> engine=innodb

-> partition by range (to_days(date)) (

-> partition p201201 values less than (to_days(\'2012-02-01\')),

-> partition p201201 values less than (to_days(\'2012-03-01\')),

-> partition p201201 values less than (to_days(\'2012-04-01\'))

-> );

mysql> insert into t select \'2012-01-02\';

Query OK, 1 row affected (0.00 sec)

Records: 1 Duplicates: 0 Warnings: 0

mysql> insert into t select \'2012-01-03\';

Query OK, 1 row affected (0.00 sec)

Records: 1 Duplicates: 0 Warnings: 0

mysql> insert into t select \'2012-01-08\';

Query OK, 1 row affected (0.01 sec)

Records: 1 Duplicates: 0 Warnings: 0

mysql> insert into t select \'2012-02-08\';

Query OK, 1 row affected (0.00 sec)

Records: 1 Duplicates: 0 Warnings: 0

mysql> insert into t select \'2012-03-08\';

Query OK, 1 row affected (0.00 sec)

Records: 1 Duplicates: 0 Warnings: 0

mysql> select * from t;

+---------------------+

| date |

+---------------------+

| 2012-01-02 00:00:00 |

| 2012-01-03 00:00:00 |

| 2012-01-08 00:00:00 |

| 2012-02-08 00:00:00 |

| 2012-03-08 00:00:00 |

+---------------------+

5 rows in set (0.00 sec)

mysql> explain partitions

-> select * from t

-> where date>=\'2012-01-01\' and date<=\'2012-01-31\'\G;

*************************** 1. row ***************************

id: 1

select_type: SIMPLE

table: t

partitions: p1

type: ALL

possible_keys: NULL

key: NULL

key_len: NULL

ref: NULL

rows: 3

Extra: Using where

1 row in set (0.00 sec)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答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分区来提高系统的性能和可维护性。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值