最近在开发项目的时候遇到一个问题,单表记录在千万级别,查询表数据速度特别慢,每次查询速度平均18s以上,我一开始的解决方式放在是索引、联合索引、字段类型、字段大小以及查询语句的优化上。后面查询速度比之前快了不少,但是感觉还不够,于是想到了mysql分区表问题上,经过合理的按照年份进行分区表操作,插叙速度大幅提升,现在每次查询数据平均1.1s至1.8s左右。现写下这篇博文分享给大家。
1.mysql分区表的目的是什么?
mysql数据库中的数据是以文件的形势存在磁盘上的,默认放在/mysql/data下面(可以通过my.cnf中的datadir来查看),一张表主要对应着三个文件,一个是frm存放表结构的,一个是myd存放表数据的,一个是myi存表索引的。如果一张表的数据量太大的话,那么myd,myi就会变的很大,查找数据就会变的很慢,这个时候我们可以利用mysql的分区功能,在物理上将这一张表对应的三个文件,分割成许多个小块,这样呢,我们查找一条数据时,就不用全部查找了,只要知道这条数据在哪一块,然后在那一块找就行了。如果表的数据太大,可能一个磁盘放不下,这个时候,我们可以把数据分配到不同的磁盘里面去。
2.怎样判断当前MySQL是否支持分区?
mysql> show variables like '%partition%';
+-------------------+-------+
| Variable_name | Value |
+-------------------+-------+
| have_partitioning | YES |
+-------------------+-------+
1 row in set (0.00 sec)
have_partintioning 的值为YES,表示支持分区。
3.mysql分区表有什么限制?(1)、一个表最多只能有1024个分区。
(2)、 MySQL5.1中,分区表达式必须是整数,或者返回整数的表达式。在MySQL5.5中提供了非整数表达式分区的支持。
(3)、如果分区字段中有主键或者唯一索引的列,那么多有主键列和唯一索引列都必须包含进来。即:分区字段要么不包含主键或者索引列,要么包含全部主键和索引列。
(4)、分区表中无法使用外键约束。
(5)、MySQL的分区适用于一个表的所有数据和索引,不能只对表数据分区而不对索引分区,也不能只对索引分区而不对表分区,也不能只对表的一部分数据分区。
4.安装时间年份对mysql的tab_griddata_tmp进行分区
ALTER TABLE tab_griddata_tmp PARTITION BY RANGE (year(datetime))
(
PARTITION p1 VALUES LESS THAN (2017),
PARTITION p2 VALUES LESS THAN (2018),
PARTITION p3 VALUES LESS THAN (2019),
PARTITION p4 VALUES LESS THAN (2020),
PARTITION p5 VALUES LESS THAN (2021),
PARTITION p6 VALUES LESS THAN (2022),
PARTITION p7 VALUES LESS THAN (2023),
PARTITION p8 VALUES LESS THAN (2024),
PARTITION p9 VALUES LESS THAN (2025),
PARTITION p10 VALUES LESS THAN (2026),
PARTITION p11 VALUES LESS THAN (2027),
PARTITION p12 VALUES LESS THAN (2028),
PARTITION p13 VALUES LESS THAN (2029),
PARTITION p14 VALUES LESS THAN (2030),
PARTITION p15 VALUES LESS THAN MAXVALUE
)
5.总结mysql分区表操作起来虽然并不麻烦,单张表最多分区表1024个,随着数据量越来越大,mysql分区表不是最终的解决方法,网上针对这个问题普遍建议是到时候做表分区、库分区,操作是一样的。
大神,这个是mysql的存储过程,我把它运用到Oracle貌似播出了,能分享一个Oracle的存储过程demo吗