`
西蜀石兰
  • 浏览: 118972 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

MySQL使用columns关键字对日期分区

 
阅读更多
最近在学习MySQL数据库建表、分区、索引一些基础知识,这篇文章将简单的介绍关于建表的一些建议、分区和索引的使用,重点介绍5.5版本之后MySQL分区对日期字段的支持。

建表(使用的引擎都是InnoDB,详情见这篇文章,MyISAM引擎已经停止开发了)
1.--除了业务功能需要的字段外,建议增加一列,使用自增id(auto_increment),同时推荐所有的字段不允许为空,因为空字段会需要额外的空间开销;
2.--将需要分区的列加入到主键之中,mysql建立分区时,如果存在主键,那么分区使用的列必须包含在主键之中;(一知半解地说说,应该和物理位置有关系,InnoDB引擎会根据主键建立聚集索引,索引和数据放在一起。)
下面是建表语句:添加自增id列,同时将需要分区的列名加入到主键中;采用COLUMNS关键字直接对日期进行分区。
CREATE TABLE `anycast_table1` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `host_id` int(11) NOT NULL,
  `zebra` varchar(20) NOT NULL DEFAULT 'N/A',
  `ospf` varchar(20) NOT NULL DEFAULT 'N/A',
  `linktest` varchar(20) NOT NULL,
  `date` datetime NOT NULL,
  `date_ymd` date NOT NULL DEFAULT '0000-00-00',
  `serviceip` varchar(256) NOT NULL DEFAULT 'N/A',
  `host_type` char(1) DEFAULT '1',
  `ospf6` varchar(20) DEFAULT 'N/A',
  PRIMARY KEY (`id`,`date`),
  KEY `hostindex` (`host_id`,`date`)
) ENGINE=InnoDB AUTO_INCREMENT=4594 DEFAULT CHARSET=gb2312
/*!50500 PARTITION BY RANGE  COLUMNS(`date`)
(PARTITION range_p1 VALUES LESS THAN ('2015-12-29') ENGINE = InnoDB,
 PARTITION range_p2 VALUES LESS THAN ('2015-12-30') ENGINE = InnoDB,
 PARTITION range_p3 VALUES LESS THAN ('2015-12-31') ENGINE = InnoDB,
 PARTITION range_p4 VALUES LESS THAN ('2016-01-01') ENGINE = InnoDB,
 PARTITION range_p5 VALUES LESS THAN (MAXVALUE) ENGINE = InnoDB) */


分区的效果
1.--读写速度加快:可以同时访问多个的物理区域,对于sum()、count()函数有效果,加快查询速度。

2.--查询速度加快:尽可能少的访问最少的数据获得查询结果,如果确切的知道某个数据在哪个区,那么引擎在执行查询语句时,只会扫描该区的数据。

对于第一点,用下面这张图张图(用Echarts画的)解释:


不使用索引和分区,扫描全表(150万的数据),需要25秒;
单独使用分区,10秒;
单独使用主键索引,5秒;
同时使用主键和分区,4秒。
由此可见,使用分区或者主键索引,可以大大降低count(*)所需要的时间,而主键索引效果又比分区好很多,这也就是为什么在建表时,建议增加一列自增id作为主键的原因之一;

使用分区更多是因为第二点,加快查询速度


这条查询语句在执行时,只使用了p1、p2分区的数据,而非全表,必然会加快查询速度。

值得一提地是在写sql语句中发现的另外两点:
1.--查询条件“1<num and num<2”和“1<num<2”使用分区的区别
2.--查询时“<、>”何时有效。
对于第一点,仍旧在已经建好的这张表上实验就能知道
使用and查询

不使用and查询

使用and查询,只扫描了p3分区;而不使用and查询时,扫描了整个分区。

对于第二点,需要重新建一张表来说明
CREATE TABLE `anycast_table` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `host_id` int(11) NOT NULL,
  `zebra` varchar(20) NOT NULL DEFAULT 'N/A',
  `ospf` varchar(20) NOT NULL DEFAULT 'N/A',
  `linktest` varchar(20) NOT NULL,
  `date` datetime NOT NULL,
  `date_ymd` date NOT NULL DEFAULT '0000-00-00',
  `serviceip` varchar(256) NOT NULL DEFAULT 'N/A',
  `host_type` char(1) DEFAULT '1',
  `ospf6` varchar(20) DEFAULT 'N/A',
  PRIMARY KEY (`id`,`date_ymd`),
  KEY `hostindex` (`host_id`,`date`)
) ENGINE=MyISAM AUTO_INCREMENT=4594 DEFAULT CHARSET=gb2312
/*!50100 PARTITION BY RANGE (dayofmonth(`date_ymd`))
(PARTITION range_p1 VALUES LESS THAN (2) ENGINE = MyISAM,
 PARTITION range_p2 VALUES LESS THAN (3) ENGINE = MyISAM,
 PARTITION range_p3 VALUES LESS THAN (4) ENGINE = MyISAM,
 PARTITION range_p4 VALUES LESS THAN (5) ENGINE = MyISAM,
 PARTITION range_p5 VALUES LESS THAN (6) ENGINE = MyISAM,
 PARTITION range_p6 VALUES LESS THAN (7) ENGINE = MyISAM,
 PARTITION range_p7 VALUES LESS THAN (8) ENGINE = MyISAM,
 PARTITION range_p8 VALUES LESS THAN (9) ENGINE = MyISAM,
 PARTITION range_p9 VALUES LESS THAN (10) ENGINE = MyISAM,
 PARTITION range_p10 VALUES LESS THAN (11) ENGINE = MyISAM,
 PARTITION range_p11 VALUES LESS THAN (12) ENGINE = MyISAM,
 PARTITION range_p12 VALUES LESS THAN (13) ENGINE = MyISAM,
 PARTITION range_p13 VALUES LESS THAN (14) ENGINE = MyISAM,
 PARTITION range_p14 VALUES LESS THAN (15) ENGINE = MyISAM,
 PARTITION range_p15 VALUES LESS THAN (16) ENGINE = MyISAM,
 PARTITION range_p16 VALUES LESS THAN (17) ENGINE = MyISAM,
 PARTITION range_p17 VALUES LESS THAN (18) ENGINE = MyISAM,
 PARTITION range_p18 VALUES LESS THAN (19) ENGINE = MyISAM,
 PARTITION range_p19 VALUES LESS THAN (20) ENGINE = MyISAM,
 PARTITION range_p20 VALUES LESS THAN (21) ENGINE = MyISAM,
 PARTITION range_p21 VALUES LESS THAN (22) ENGINE = MyISAM,
 PARTITION range_p22 VALUES LESS THAN (23) ENGINE = MyISAM,
 PARTITION range_p23 VALUES LESS THAN (24) ENGINE = MyISAM,
 PARTITION range_p24 VALUES LESS THAN (25) ENGINE = MyISAM,
 PARTITION range_p25 VALUES LESS THAN (26) ENGINE = MyISAM,
 PARTITION range_p26 VALUES LESS THAN (27) ENGINE = MyISAM,
 PARTITION range_p27 VALUES LESS THAN (28) ENGINE = MyISAM,
 PARTITION range_p28 VALUES LESS THAN (29) ENGINE = MyISAM,
 PARTITION range_p29 VALUES LESS THAN (30) ENGINE = MyISAM,
 PARTITION range_p30 VALUES LESS THAN (31) ENGINE = MyISAM,
 PARTITION range_p31 VALUES LESS THAN (32) ENGINE = MyISAM) */


建表语句有点长,看着有点蛋疼,实际上就是根据月份的天数分了31个区,每个月的同一天数据都会塞到一个分区,用着也很蛋疼,开发的时候数据比较少,项目跑上3年,分区跟没建一样,这也是我不能理解的地方。
闲话少说,还是回归正题,当我在这张表上使用">、<"查询时,发现分区失效了。

这种分区方式其实是在MySQL5.5之前普遍地做法,看了一篇老外的博客,上面是这么解释的:使用YEAR或TO_DAYS定义一个分区的确让人费解,查询时不得不使用赤裸列,因为加了函数的查询不能识别分区。

其实并不准确,这种分区方式,仅支持部分查询,比如“in、=”,再贴两张图吧




这也是同事当初给我说的,查询时尽量用in,并没有错。

顺便解释一下为什么第二张表会多出一个日期字段date_ymd,date字段类型是datetime,入库时带上时间,直接根据这个字段分区,是可以的。关键是,没法用,因为,这么建分区,不支持上文说的“<、>”,所以才会使用触发器增加了一个新的字段date_ymd,查询时,现根据date_ymd字段确定分区,而后在这个分区中查询数据。
分享到:
评论

相关推荐

    深入浅析MySQL COLUMNS分区

    1.针对日期字段的分区就不需要再使用函数进行转换了,例如针对date字段进行分区不需要再使用YEAR()表达式进行转换。 2.COLUMN分区支持多个字段作为分区键但是不支持表达式作为分区键。 COLUMNS支持的类型 整形支持:...

    mysql-存储分区-实验八.docx

    - **Range Columns分区**:与Range分区类似,但可以使用多列作为分区键。 - **List分区**:根据列表中的特定值进行分区,值必须在预先定义的列表内。 - **List Columns分区**:与List分区相似,但支持多列分区键...

    add_columns.txt

    mysql_add_columns mysql在一个表中添加记录动态在另一表中添加列。

    mysql mysql基本使用

    5. mysql.columns_priv:存储列级别的权限信息,包括用户对列的访问权限。 6. mysql.procs_priv:存储存储过程和存储函数级别的权限信息,包括用户对存储过程和存储函数的访问权限。 7. mysql.proxies_priv:存储...

    mysql使用

    在本篇文章中,我们将对 MySQL 的基本使用进行详细的讲解,包括数据的导出和导入、数据库的创建和删除、表的操作等基本知识点。 一、数据的导出和导入 MySQL 中提供了多种方式来导出和导入数据,以下是其中的一些...

    Mysql相关使用总结

    当使用 MySQL 关键字作为数据库名、表名或字段名时,需要将关键字用反引号 (``) 包围起来以避免冲突。 #### MySQL 数据库操作 - **创建数据库**: ```sql CREATE DATABASE IF NOT EXISTS db_name DEFAULT ...

    基于CentOS的Mysql使用说明文档

    在本篇基于CentOS的MySQL使用说明文档中,我们将探讨如何在 CentOS 操作系统上安装、配置、管理和操作MySQL数据库。MySQL是一个广泛使用的开源关系型数据库管理系统,它提供了高效、可靠的数据存储解决方案。 首先...

    总结MySQL的分区

    本文针对MySQL的分区技术进行了全面的介绍和总结,希望能对使用MySQL数据库的用户在实施分区时提供帮助。在实际应用中,设计分区策略时应根据实际应用场景和数据分布特性,选择合适的分区类型和分区键,以最大化利用...

    MYSQL8.0中文参考手册

    - **分区表的增强**:支持更多类型的分区表达式,如LIST分区和RANGE COLUMNS分区。 - **性能 Schema的改进**:提供了更丰富的性能监控和分析数据。 - **异步复制**:允许主服务器和从服务器在不同速度下运行,...

    如何用hash关键字提高数据库性能

    如果不使用`hash关键字`,直接对这两列建立索引会导致巨大的磁盘开销,并且查询性能也会受到严重影响。通过使用`hash关键字`,每个记录的`hash`值仅占用4字节的空间,相比于原始字符串的50+50字节,极大地减少了磁盘...

    mysql51.zip

    - **分区功能增强**:MySQL 5.1对分区表进行了改进,支持更多的分区类型,如线性哈希和RANGE COLUMNS,这有助于大数据管理和查询性能。 - **触发器**:5.1版开始支持触发器,允许用户在特定的数据库操作(如INSERT...

    sqlserver2005 创建分区表 分区索引 注意事宜 分区索引

    如果经常执行跨分区的全表操作,建议使用与分区数相同的文件组,并将它们分布在不同的物理磁盘上,以便利用并行处理加速处理速度。 - **步骤3:创建分区函数** 分区函数定义了数据如何分配到各个分区。例如,创建...

    MySQL-5.7.36-winx64

    10. **分区功能**:MySQL 5.7对分区功能进行了扩展,包括更多的分区策略和对分区表的操作优化。 压缩包中的"mysql-5.7.36-winx64"可能包含以下内容:安装程序、配置文件、数据库服务器可执行文件、客户端工具、示例...

    测试使用的MySQL数据库

    基础的权限表主要包括`mysql.user`、`mysql.db`、`mysql.tables_priv`和`mysql.columns_priv`等。`mysql.user`表存储了所有用户的登录信息和全局权限;`mysql.db`表用于定义用户对特定数据库的访问权限;`mysql....

    MySql常用查询命令操作大全

    MySQL是一种广泛使用的开源关系型数据库管理系统,其丰富的查询命令使得数据操作变得简单高效。以下是一些MySQL中的常用查询命令操作: 1. **查看版本信息**: - `mysql&gt; select version();` 可以用来查看MySQL...

    PHP和MySQL Web开发第4版pdf以及源码

    3.6.2 使用asort()函数和ksort()函数对相关数组排序 3.6.3 反向排序 3.7 多维数组的排序 3.7.1 用户定义排序 3.7.2 反向用户排序 3.8 对数组进行重新排序 3.8.1 使用shuffle()函数 3.8.2 使用array_reverse()...

    MySQL ER设计工具 Workbench的使用教程

    在MySQL Workbench中,还可以设定字段的排序规则(Collation)和其它高级选项,如触发器(Trigger)和分区(Partitioning)。 在设计表时,还可以设定主键、外键以及默认值等属性。主键用于唯一标识表中的每条记录...

Global site tag (gtag.js) - Google Analytics