一个非常大的表的 SQL 分区
Posted
技术标签:
【中文标题】一个非常大的表的 SQL 分区【英文标题】:SQL Partitioning of a very large table 【发布时间】:2019-10-03 21:50:57 【问题描述】:我正在尝试对名为 companyScores 的非常大的 mysql 表(6000 万行和 50 列)进行分区。 基本上,该表包含公司(列 varchar “company_idx”,唯一 ID 从 0 到 10,000 个公司)及其各自的时间戳(列“timestamp”)和分数“Scores”(列“Scores”)。 我想在每个分区中包含大约 500 家公司。 请让我知道以下是否可以完成这项工作?
ALTER TABLE `companyScores`
PARTITION BY RANGE( company_idx ) (
PARTITION p0 VALUES LESS THAN (500),
PARTITION p1 VALUES LESS THAN (1000),
PARTITION p2 VALUES LESS THAN (1500),
PARTITION p3 VALUES LESS THAN (2000),
and so on...
);
以上方法有用吗?
另外,一旦这个数据库被分区,我们是否可以轻松地将新值插入到这个数据库中?
【问题讨论】:
【参考方案1】:以上方法有用吗?
没有。有几个原因。
如果company_idx
是varchar,则需要使用RANGE COLUMNS
。 RANGE
分区仅适用于整数。如果您尝试在 varchar 上使用 RANGE
分区,则会收到以下错误:
ERROR 1659 (HY000): Field 'company_idx' is of a not allowed type for this type of partitioning
假设你改正了,你还有另一个问题:
您的分区子句使用整数值,而不是带引号的字符串值。这些是不同的类型,分区引擎不会使用它们来定义分区。如果你尝试,你会出现这个错误:
ERROR 1654 (HY000): Partition column values of incorrect type
假设您通过引用数字来纠正这一点,您还有另一个问题:
您在字符串 1000 之前列出了 500 的分区,但在词法上,字符串 '500' 应该在字符串 '1000' 之后。 RANGE 或 RANGE COLUMNS 分区必须按升序声明。如果您尝试按照您的顺序执行此操作,您将收到此错误:
ERROR 1493 (HY000): VALUES LESS THAN value must be strictly increasing for each partition
假设您更正了订单,它可以工作,但它可能无法达到您想要的效果:
CREATE TABLE `companyScores` (
`company_idx` varchar(10) NOT NULL,
PRIMARY KEY (`company_idx`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
/*!50500 PARTITION BY RANGE COLUMNS(company_idx)
(PARTITION p1 VALUES LESS THAN ('1000') ENGINE = InnoDB,
PARTITION p2 VALUES LESS THAN ('1500') ENGINE = InnoDB,
PARTITION p3 VALUES LESS THAN ('2000') ENGINE = InnoDB,
PARTITION p0 VALUES LESS THAN ('500') ENGINE = InnoDB) */
现在你又问了一个问题:
另外,一旦它被分区,我们是否可以轻松地将新值插入到这个数据库中?
如果你插入一个未被你定义的分区覆盖的新值,你会得到这个错误:
mysql> insert into companyScores set company_idx = '700';
ERROR 1526 (HY000): Table has no partition for value from column_list
这是为什么呢?您的 company_idx 分区小于 1000 对吗?
没有。您的 company_idx 分区小于 string '1000'。您尝试插入字符串“700”,它在词法上大于“500”,以及所有其他分区。因此它超出了定义的任何分区。
如果将 customer_idx 更改为整数列,则可以解决上述所有问题。
【讨论】:
感谢您所做的一切,它现在运行良好。不过我还有一个问题,当我想向特定分区插入新行时,我该怎么做?我是否说“INSERT INTO companyScores PARTITION (p500) ...”它是否也添加到了整个表格中?还是只有分区? 新行仅存储在一个分区中,具体取决于您为表声明的分区方案。没有“整表”——表只是其分区的总和。 所以我总是需要声明将我的新数据插入到哪个分区? 不,您从不需要声明哪个分区。它由您插入的行中的值决定。以上是关于一个非常大的表的 SQL 分区的主要内容,如果未能解决你的问题,请参考以下文章