Mysql分区表局限性总结

2024-04-27 09:18

本文主要是介绍Mysql分区表局限性总结,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Mysql5.1已经发行很久了,本文根据官方文档的翻译和自己的一些测试,对Mysql分区表的局限性做了一些总结,因为个人能力以及测试环境的原因,有可能有错误的地方,还请大家看到能及时指出,当然有兴趣的朋友可以去官方网站查阅。

本文测试的版本

mysql> select version();
+————+
| version()  |
+————+
| 5.1.33-log |
+————+
1 row in set (0.00 sec)

一、关于Partitioning Keys, Primary Keys, and Unique Keys的限制

在5.1中分区表对唯一约束有明确的规定,每一个唯一约束必须包含在分区表的分区键(也包括主键约束)。
这句话也许不好理解,我们做几个实验:

CREATE TABLE t1
(      id INT NOT NULL,
uid INT NOT NULL,
PRIMARY KEY (id)
)
PARTITION BY RANGE (id)
(PARTITION p0 VALUES LESS THAN(5) ENGINE = INNODB,
PARTITION p1 VALUES LESS THAN(10) ENGINE = INNODB
);

CREATE TABLE t1
(      id INT NOT NULL,
uid INT NOT NULL,
PRIMARY KEY (id)
)
PARTITION BY RANGE (id)
(PARTITION p0 VALUES LESS THAN(5) ENGINE = MyISAM DATA DIRECTORY=’/tmp’ INDEX DIRECTORY=’/tmp’,
PARTITION p1 VALUES LESS THAN(10) ENGINE = MyISAM DATA DIRECTORY=’/tmp’ INDEX DIRECTORY=’/tmp’
);

mysql> CREATE TABLE t1
-> (      id INT NOT NULL,
->        uid INT NOT NULL,
->        PRIMARY KEY (id),
->        UNIQUE KEY (uid)
-> )
-> PARTITION BY RANGE (id)
-> (PARTITION p0 VALUES LESS THAN(5),
->  PARTITION p1 VALUES LESS THAN(10)
-> );
ERROR 1503 (HY000): A UNIQUE INDEX must include all columns in the table’s partitioning function

二、关于存储引擎的限制
2.1 MERGE引擎不支持分区,分区表也不支持merge。
2.2 FEDERATED引擎不支持分区。这限制可能会在以后的版本去掉。
2.3 CSV引擎不支持分区
2.4 BLACKHOLE引擎不支持分区
2.5 在NDBCLUSTER引擎上使用分区表,分区类型只能是KEY(or LINEAR KEY) 分区。
2.6 当升级MYSQL的时候,如果你有使用了KEY分区的表(不管是什么引擎,NDBCLUSTER除外),那么你需要把这个表dumped在reloaded。
2.7 分区表的所有分区或者子分区的存储引擎必须相同,这个限制也许会在以后的版本取消。
不指定任何引擎(使用默认引擎)。
所有分区或者子分区指定相同引擎。

三、关于函数的限制
在mysql5.1中建立分区表的语句中,只能包含下列函数:
ABS()
CEILING() and FLOOR() (在使用这2个函数的建立分区表的前提是使用函数的分区键是INT类型),例如

mysql> CREATE TABLE t (c FLOAT) PARTITION BY LIST( FLOOR(c) )(
-> PARTITION p0 VALUES IN (1,3,5),
-> PARTITION p1 VALUES IN (2,4,6)
-> );;
ERROR 1491 (HY000): The PARTITION function returns the wrong type

mysql> CREATE TABLE t (c int) PARTITION BY LIST( FLOOR(c) )(
-> PARTITION p0 VALUES IN (1,3,5),
-> PARTITION p1 VALUES IN (2,4,6)
-> );
Query OK, 0 rows affected (0.01 sec)

DAY()
DAYOFMONTH()
DAYOFWEEK()
DAYOFYEAR()
DATEDIFF()
EXTRACT()
HOUR()
MICROSECOND()
MINUTE()
MOD()
MONTH()
QUARTER()
SECOND()
TIME_TO_SEC()
TO_DAYS()
WEEKDAY()
YEAR()
YEARWEEK()

四、其他限制

4.1 对象限制
下面这些对象在不能出现在分区表达式
Stored functions, stored procedures, UDFs, or plugins.
Declared variables or user variables.

4.2 运算限制
支持加减乘等运算出现在分区表达式,但是运算后的结果必须是一个INT或者NULL。 |, &, ^, <<, >>, , ~ 等不允许出现在分区表达式。

4.3 sql_mode限制
官方强烈建议你在创建分区表后,永远别改变mysql的sql_mode。因为在不同的模式下,某些函数或者运算返回的结果可能会不一样。

4.4 Performance considerations.(省略)

4.5 最多支持1024个分区,包括子分区。
当你建立分区表包含很多分区但没有超过1024限制的时候,如果报错 Got error 24 from storage engine,那意味着你需要增大open_files_limit参数。

4.6 不支持外键。MYSQL中,INNODB引擎才支持外键。

4.7 不支持FULLTEXT indexes(全文索引),包括MYISAM引擎。

mysql> CREATE TABLE articles (
-> id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
-> title VARCHAR(200),
-> body TEXT,
-> FULLTEXT (title,body)
-> )
-> PARTITION BY HASH(id)
-> PARTITIONS 4;
ERROR 1214 (HY000): The used table type doesn’t support FULLTEXT indexes

4.8 不支持spatial column types。
4.9 临时表不能被分区。

mysql> CREATE Temporary TABLE t1
-> (      id INT NOT NULL,
->        uid INT NOT NULL,
->        PRIMARY KEY (id)
-> )
-> PARTITION BY RANGE (id)
-> (PARTITION p0 VALUES LESS THAN(5) ENGINE = MyISAM,
->  PARTITION p1 VALUES LESS THAN(10) ENGINE = MyISAM
-> );
ERROR 1562 (HY000): Cannot create temporary table with partitions

4.10 log table不支持分区。

mysql> alter table mysql.slow_log PARTITION BY KEY(start_time) PARTITIONS 2;
ERROR 1221 (HY000): Incorrect usage of PARTITION and log table

5.11 分区键必须是INT类型,或者通过表达式返回INT类型,可以为NULL。唯一的例外是当分区类型为KEY分区的时候,可以使用其他类型的列作为分区键( BLOB or TEXT 列除外)。

mysql> CREATE TABLE tkc (c1 CHAR)
-> PARTITION BY KEY(c1)
-> PARTITIONS 4;
Query OK, 0 rows affected (0.00 sec)

mysql> CREATE TABLE tkc2 (c1 CHAR)
-> PARTITION BY HASH(c1)
-> PARTITIONS 4;
ERROR 1491 (HY000): The PARTITION function returns the wrong type

mysql> CREATE TABLE tkc3 (c1 INT)
-> PARTITION BY HASH(c1)
-> PARTITIONS 4;
Query OK, 0 rows affected (0.00 sec)

5.12 分区键不能是一个子查询。 A partitioning key may not be a subquery, even if that subquery resolves to an integer value or NULL

5.13 只有RANG和LIST分区能进行子分区。HASH和KEY分区不能进行子分区。

5.14 分区表不支持Key caches。

mysql> SET GLOBAL keycache1.key_buffer_size=128*1024;
Query OK, 0 rows affected (0.00 sec)
mysql> CACHE INDEX login,user_msg,user_msg_p IN keycache1;
+—————–+——————–+———-+———————————————————————+
| Table           | Op                 | Msg_type | Msg_text                                                            |
+—————–+——————–+———-+———————————————————————+
| test.login      | assign_to_keycache | status   | OK                                                                  |
| test.user_msg   | assign_to_keycache | status   | OK                                                                  |
| test.user_msg_p | assign_to_keycache | note     | The storage engine for the table doesn’t support assign_to_keycache |
+—————–+——————–+———-+———————————————————————+
3 rows in set (0.00 sec)

5.15 分区表不支持INSERT DELAYED.

mysql> insert  DELAYED into user_msg_p values(18156629,0,0,0,0,0,0,0,0,0);
ERROR 1616 (HY000): DELAYED option not supported for table ‘user_msg_p’

5.16 DATA DIRECTORY 和 INDEX DIRECTORY 参数在分区表将被忽略。
这个限制应该不存在了:
注:在创建InnoDB引擎的情况下,还是会忽略,即使已经打开innodb_file_per_table,还是需要手动做符号连接。
例如:
drop table if exists ts ;
CREATE TABLE ts (id INT, purchased DATE)
ENGINE=innodb
PARTITION BY RANGE(YEAR(purchased))
SUBPARTITION BY HASH(id)
(
PARTITION p0 VALUES LESS THAN (1990)
(
SUBPARTITION s0
DATA DIRECTORY=’/usr/local/mysql/data0′
INDEX DIRECTORY=’/usr/local/mysql/index0′,
SUBPARTITION s1
DATA DIRECTORY=’/usr/local/mysql/data1′
INDEX DIRECTORY=’/usr/local/mysql/index1′
),
PARTITION p1 VALUES LESS THAN (MAXVALUE)
(
SUBPARTITION s2
DATA DIRECTORY=’/usr/local/mysql/data1′
INDEX DIRECTORY=’/usr/local/mysql/index1′,
SUBPARTITION s3
DATA DIRECTORY=’/usr/local/mysql/data2′
INDEX DIRECTORY=’/usr/local/mysql/index2′
)
);
手动做完符号连接后如下:
-rw-rw—- 1 mysql mysql     8596 02-28 22:07 ts.frm
-rw-rw—- 1 mysql mysql       56 02-28 22:07 ts.par
lrwxrwxrwx 1 mysql mysql       40 02-28 22:30 ts#P#p0#SP#s0.ibd -> /usr/local/mysql/data0/ts#P#p0#SP#s0.ibd
lrwxrwxrwx 1 mysql mysql       40 02-28 22:31 ts#P#p0#SP#s1.ibd -> /usr/local/mysql/data0/ts#P#p0#SP#s1.ibd
lrwxrwxrwx 1 mysql mysql       40 02-28 22:31 ts#P#p1#SP#s2.ibd -> /usr/local/mysql/data0/ts#P#p1#SP#s2.ibd
lrwxrwxrwx 1 mysql mysql       40 02-28 22:31 ts#P#p1#SP#s3.ibd -> /usr/local/mysql/data0/ts#P#p1#SP#s3.ibd

mysql> CREATE TABLE t1
-> (      id INT NOT NULL,
->        uid INT NOT NULL,
->        PRIMARY KEY (id)
-> )
-> PARTITION BY RANGE (id)
-> (PARTITION p0 VALUES LESS THAN(5) ENGINE = MyISAM DATA DIRECTORY=’/tmp’ INDEX DIRECTORY=’/tmp’,
->  PARTITION p1 VALUES LESS THAN(10) ENGINE = MyISAM DATA DIRECTORY=’/tmp’ INDEX DIRECTORY=’/tmp’
-> );
Query OK, 0 rows affected (0.01 sec)

5.17 分区表不支持mysqlcheck和myisamchk
在5.1.33版本中已经支持mysqlcheck和myisamchk

./mysqlcheck -u -p -r test user_msg_p;
test.user_msg_p                                    OK

./myisamchk -i /u01/data/test/user_msg_p#P#p0.MYI
Checking MyISAM file: /u01/data/test/user_msg_p#P#p0.MYI
Data records: 4423615   Deleted blocks:       0
- check file-size
- check record delete-chain
- check key delete-chain
- check index reference
- check data record references index: 1
Key:  1:  Keyblocks used:  98%  Packed:    0%  Max levels:  4
Total:    Keyblocks used:  98%  Packed:    0%

User time 0.97, System time 0.02
Maximum resident set size 0, Integral resident set size 0
Non-physical pagefaults 324, Physical pagefaults 0, Swaps 0
Blocks in 0 out 0, Messages in 0 out 0, Signals 0
Voluntary context switches 1, Involuntary context switches 5

5.18 分区表的分区键创建索引,那么这个索引也将被分区。分区键没有全局索引一说。
5.19 在分区表使用ALTER TABLE … ORDER BY,只能在每个分区内进行order by。

这篇关于Mysql分区表局限性总结的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/940107

相关文章

MySQL中EXISTS与IN用法使用与对比分析

《MySQL中EXISTS与IN用法使用与对比分析》在MySQL中,EXISTS和IN都用于子查询中根据另一个查询的结果来过滤主查询的记录,本文将基于工作原理、效率和应用场景进行全面对比... 目录一、基本用法详解1. IN 运算符2. EXISTS 运算符二、EXISTS 与 IN 的选择策略三、性能对比

MySQL常用字符串函数示例和场景介绍

《MySQL常用字符串函数示例和场景介绍》MySQL提供了丰富的字符串函数帮助我们高效地对字符串进行处理、转换和分析,本文我将全面且深入地介绍MySQL常用的字符串函数,并结合具体示例和场景,帮你熟练... 目录一、字符串函数概述1.1 字符串函数的作用1.2 字符串函数分类二、字符串长度与统计函数2.1

SQL Server跟踪自动统计信息更新实战指南

《SQLServer跟踪自动统计信息更新实战指南》本文详解SQLServer自动统计信息更新的跟踪方法,推荐使用扩展事件实时捕获更新操作及详细信息,同时结合系统视图快速检查统计信息状态,重点强调修... 目录SQL Server 如何跟踪自动统计信息更新:深入解析与实战指南 核心跟踪方法1️⃣ 利用系统目录

MySQL 内存使用率常用分析语句

《MySQL内存使用率常用分析语句》用户整理了MySQL内存占用过高的分析方法,涵盖操作系统层确认及数据库层bufferpool、内存模块差值、线程状态、performance_schema性能数据... 目录一、 OS层二、 DB层1. 全局情况2. 内存占js用详情最近连续遇到mysql内存占用过高导致

Mysql中设计数据表的过程解析

《Mysql中设计数据表的过程解析》数据库约束通过NOTNULL、UNIQUE、DEFAULT、主键和外键等规则保障数据完整性,自动校验数据,减少人工错误,提升数据一致性和业务逻辑严谨性,本文介绍My... 目录1.引言2.NOT NULL——制定某列不可以存储NULL值2.UNIQUE——保证某一列的每一

解密SQL查询语句执行的过程

《解密SQL查询语句执行的过程》文章讲解了SQL语句的执行流程,涵盖解析、优化、执行三个核心阶段,并介绍执行计划查看方法EXPLAIN,同时提出性能优化技巧如合理使用索引、避免SELECT*、JOIN... 目录1. SQL语句的基本结构2. SQL语句的执行过程3. SQL语句的执行计划4. 常见的性能优

SQL Server 中的 WITH (NOLOCK) 示例详解

《SQLServer中的WITH(NOLOCK)示例详解》SQLServer中的WITH(NOLOCK)是一种表提示,等同于READUNCOMMITTED隔离级别,允许查询在不获取共享锁的情... 目录SQL Server 中的 WITH (NOLOCK) 详解一、WITH (NOLOCK) 的本质二、工作

MySQL 强制使用特定索引的操作

《MySQL强制使用特定索引的操作》MySQL可通过FORCEINDEX、USEINDEX等语法强制查询使用特定索引,但优化器可能不采纳,需结合EXPLAIN分析执行计划,避免性能下降,注意版本差异... 目录1. 使用FORCE INDEX语法2. 使用USE INDEX语法3. 使用IGNORE IND

SQL Server安装时候没有中文选项的解决方法

《SQLServer安装时候没有中文选项的解决方法》用户安装SQLServer时界面全英文,无中文选项,通过修改安装设置中的国家或地区为中文中国,重启安装程序后界面恢复中文,解决了问题,对SQLSe... 你是不是在安装SQL Server时候发现安装界面和别人不同,并且无论如何都没有中文选项?这个问题也

2025版mysql8.0.41 winx64 手动安装详细教程

《2025版mysql8.0.41winx64手动安装详细教程》本文指导Windows系统下MySQL安装配置,包含解压、设置环境变量、my.ini配置、初始化密码获取、服务安装与手动启动等步骤,... 目录一、下载安装包二、配置环境变量三、安装配置四、启动 mysql 服务,修改密码一、下载安装包安装地