首页 > 解决方案 > 一个非常大的表的 SQL 分区

问题描述

我正在尝试对名为 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...
);

上面的方法有用吗?

此外,一旦它被分区,我们是否可以轻松地将新值插入到这个数据库中?

标签: mysqlsqldatabase

解决方案


上面的方法有用吗?

不,有几个原因。

如果company_idx是 varchar,则需要使用RANGE COLUMNS. RANGE分区仅适用于整数。如果您尝试RANGE在 varchar 上使用分区,则会收到以下错误:

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 分区小于字符串“1000”。您尝试插入字符串“700”,它在词法上大于“500”,以及所有其他分区。因此它超出了定义的任何分区。

如果将 customer_idx 更改为整数列,则可以解决上述所有问题。


推荐阅读