需要帮助在位列上对mysql表进行分区,并在结果分区上进行子分区吗

o2g1uqev  于 2021-06-17  发布在  Mysql
关注(0)|答案(1)|浏览(381)

我需要一些帮助来弄清楚如何在mysql数据库中对下表进行分区,这样我就有了2个分区,1个活动用户( active 列=true)和另一个非活动用户。然后我想将非活动用户分区按年份(在 archive_key 数据类型为年份(4)的列)。我想我知道如何做到这一点,但我不敢尝试,以防我执行不正确。
有人能帮我做到这一点吗?我目前正在使用MySQL5.7和8版本。感谢您的建议。

CREATE TABLE users_table (
  row_id int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
  first_name varchar(255) DEFAULT NULL,
  last_name varchar(255) DEFAULT NULL,
  ...
  createdby varchar(255) DEFAULT NULL,
  createdat datetime DEFAULT NULL,
  lastmodby varchar(255) DEFAULT NULL,
  lastmodat datetime DEFAULT NULL,
  active bit(1) NOT NULL DEFAULT b'0',
  archive_key year(4) GENERATED ALWAYS AS (YEAR(createdat)) STORED,
  PRIMARY KEY (row_id, active),
)
ENGINE = INNODB,
AUTO_INCREMENT = 84771,
AVG_ROW_LENGTH = 166,
CHARACTER SET utf8,
COLLATE utf8_unicode_ci;

顺便说一句,我喜欢分区给你的灵活性!我真是太棒了!

lvmkulzt

lvmkulzt1#

子分区
mysql对分区时可以做什么和不能做什么有很大的限制,引用5.7手册:
可以对按范围或列表分区的表进行子分区。子分区可以使用哈希或键分区
这意味着你看到的是这样的东西:

CREATE TABLE users_table (
  row_id int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
  first_name varchar(255) DEFAULT NULL,
  last_name varchar(255) DEFAULT NULL,
  createdby varchar(255) DEFAULT NULL,
  createdat datetime DEFAULT NULL,
  lastmodby varchar(255) DEFAULT NULL,
  lastmodat datetime DEFAULT NULL,
  active bit(1) NOT NULL DEFAULT b'0',
  archive_key year(4),
  PRIMARY KEY (row_id, active, archive_key)
)
       ENGINE = INNODB,
       CHARACTER SET utf8,
       COLLATE utf8_unicode_ci
       PARTITION BY LIST(active)
           SUBPARTITION BY HASH(`archive_key`)
           SUBPARTITIONS 4
       (
            PARTITION inactive VALUES IN (0),
            PARTITION active   VALUES IN (1)
       );

请注意,您需要包括 archive_key 在pk中避免
错误1503(hy000):主键必须包含表分区函数中的所有列
分割意见
不,它不摇滚。本论坛上介绍的大多数用例在使用分区的情况下运行的速度并不比不使用分区的情况快。在某些情况下,它们跑得比较慢。
当然,有很多选择。我所看到的唯一一个实际绩效改进是 PARTITION BY RANGE ,但即使这样,也只适用于狭窄的用例(清除时间序列,“查找最近的”,工作集位于一个具有“坏”索引、可传输表空间的分区中)。细节
“分区修剪”会加快查询速度,这是一个神话。具有适当索引的非分区表可能至少运行同样快。
注意:要利用添加(或删除)分区,必须重新评估索引。
在你的例子中,与

INDEX(active, createdat)   -- in this order

WHERE active = 1
  AND createdat >= '2017/01/01'
  AND createdat  < '2017/01/01' + INTERVAL 1 YEAR

INDEX(active, active_key)   -- in this order

WHERE active = 1
  AND archive_key = '2017'

(前者不需要生成的列。)

相关问题