谨慎使用MYSQL表分区

本文涉及的产品
RDS AI 助手,专业版
RDS MySQL DuckDB 分析主实例,基础系列 4核8GB
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
简介:

test1表是未分区

test2表是hash分区

以下是两个表的表结构:

mysql> show create table test1;
+-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table                                                                                                                                                                                      |
+-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| test1 | CREATE TABLE `test1` (
  `id` int(11) NOT NULL,
  `tid` int(11) DEFAULT NULL,
  `name` varchar(10) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `tid` (`tid`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
+-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

 

mysql> show create table test2;
+-------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table                                                                                                                                                                                                                                       |
+-------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| test2 | CREATE TABLE `test2` (
  `id` int(11) NOT NULL,
  `tid` int(11) DEFAULT NULL,
  `name` varchar(10) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `tid` (`tid`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
/*!50100 PARTITION BY HASH (id)
PARTITIONS 10 */ |

+-------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.01 sec)

在主键id列上用上hash分区。

 

如果是在主键上查询,那么分区要比不分区性能高,例如:

mysql> explain partitions select * from test1 where id in (86,777,432345);
+----+-------------+-------+------------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type | table | partitions | type  | possible_keys | key     | key_len | ref  | rows | Extra       |
+----+-------------+-------+------------+-------+---------------+---------+---------+------+------+-------------+
|  1 | SIMPLE      | test1 | NULL       | range | PRIMARY       | PRIMARY | 4       | NULL |    3 | Using where |
+----+-------------+-------+------------+-------+---------------+---------+---------+------+------+-------------+
1 row in set (0.06 sec)

mysql> explain partitions select * from test2 where id in (86,777,432345); 
+----+-------------+-------+------------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type | table | partitions | type  | possible_keys | key     | key_len | ref  | rows | Extra       |
+----+-------------+-------+------------+-------+---------------+---------+---------+------+------+-------------+
|  1 | SIMPLE      | test2 | p5,p6,p7   | range | PRIMARY       | PRIMARY | 4       | NULL |    3 | Using where |
+----+-------------+-------+------------+-------+---------------+---------+---------+------+------+-------------+
1 row in set (0.01 sec)
 

只在分区P5/6/7上就扫描到了记录,减少了过多的磁盘IO。

但如果在索引tid上查询,性能就很低了。

mysql>  explain partitions select * from test1 where tid = 86419804; 
+----+-------------+-------+------------+------+---------------+------+---------+-------+------+-------------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref   | rows | Extra       |
+----+-------------+-------+------------+------+---------------+------+---------+-------+------+-------------+
|  1 | SIMPLE      | test1 | NULL       | ref  | tid           | tid  | 5       | const |    1 | Using where |
+----+-------------+-------+------------+------+---------------+------+---------+-------+------+-------------+
1 row in set (0.00 sec)

mysql>  explain partitions select * from test2 where tid = 86419804; 
+----+-------------+-------+-------------------------------+------+---------------+------+---------+-------+------+-------------+
| id | select_type | table | partitions                    | type | possible_keys | key  | key_len | ref   | rows | Extra       |
+----+-------------+-------+-------------------------------+------+---------------+------+---------+-------+------+-------------+
|  1 | SIMPLE      | test2 | p0,p1,p2,p3,p4,p5,p6,p7,p8,p9 | ref  | tid           | tid  | 5       | const |   10 | Using where |
+----+-------------+-------+-------------------------------+------+---------------+------+---------+-------+------+-------------+
1 row in set (0.00 sec)
 

要扫描10个分区,才能得到结果。

mysql> select sql_no_cache * from test1 where tid=86419804; 
+----+----------+------+
| id | tid      | name |
+----+----------+------+
| 11 | 86419804 | abc2 |
+----+----------+------+
1 row in set (0.40 sec)

mysql> select sql_no_cache * from test2 where tid=86419804; 
+----+----------+------+
| id | tid      | name |
+----+----------+------+
| 11 | 86419804 | abc2 |
+----+----------+------+
1 row in set (1.98 sec)

分区后的查询结果要比未分区的慢很多。

结论:分区规则仅限制在主键上使用,性能会有提高,在其他字段上使用,即使有索引,性能也会很差。

 



本文转自 liang3391 51CTO博客,原文链接:http://blog.51cto.com/liang3391/844523

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。   相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情: https://www.aliyun.com/product/rds/mysql 
相关文章
|
存储 固态存储 关系型数据库
Mysql数据库表分区存储到指定磁盘路径
0. 前提: mysql5.6.6以上的版本以上的版本才支持单表指定目录,且目录权限是mysql:mysql。 在mysql中数据文件存放于在my.cnf中datadir指定的路径,使用的表引擎不同产生的文件格式、表文件个数也会有所差异。 mysql的表引擎有多种,表的扩展名也不一样,如innodb用“ .ibd”,archive用“.arc ”,csv用“.csv”等。
Mysql数据库表分区存储到指定磁盘路径
|
存储 关系型数据库 MySQL
mysql按天自动生成表分区的执行语句
mysql按天自动生成表分区的执行语句
523 0
|
关系型数据库 MySQL
Mysql 表分区创建方法
Mysql 表分区创建方法
|
存储 关系型数据库 MySQL
(十九)MySQL之表分区篇:涨知识了!携手共探鲜为人知的表分区!
分库分表相信大家都听说过,但(partitioning)表分区这个概念却鲜为人知,MySQL在5.1版本中开始支持了表分区技术,同时在MySQL5.5中进行了优化,自从MySQL支持的绝大部分引擎都开启了表分区功能。
1526 2
|
存储 关系型数据库 MySQL
MySQL表分区的选择与实践小结
当面对百万或千万级数据量的表,即使有索引,查询速度也可能较慢。此时,可以采取分库、分表或分区策略来提升性能。分库分表涉及创建新数据库或表,可能需更改逻辑代码;
266 3
|
关系型数据库 MySQL
MySQL 横向表分区之RANGE分区小结
MySQL 横向表分区之RANGE分区小结
295 0
MySQL 横向表分区之RANGE分区小结
|
SQL 存储 关系型数据库
【SQL应知应会】表分区(五)• MySQL版
【SQL应知应会】表分区(五)• MySQL版
462 0
|
SQL 存储 Oracle
【SQL应知应会】表分区(四)• MySQL版
【SQL应知应会】表分区(四)• MySQL版
431 0
|
SQL 存储 关系型数据库
【SQL应知应会】表分区(三)• MySQL版
【SQL应知应会】表分区(三)• MySQL版
312 0
|
SQL 存储 算法
【SQL应知应会】表分区(二)• MySQL版
【SQL应知应会】表分区(二)• MySQL版
401 0

推荐镜像

更多