出于性能原因,我想根据枚举字段对表进行分区。该表预计将包含大量数据,从应用程序的角度来看,在此枚举列上进行分区非常有意义。
这是我想做的一个最小的例子:
DROP TABLE IF EXISTS test_performance_data;
CREATE TABLE test_performance_data
(
id INT AUTO_INCREMENT PRIMARY KEY,
resource_type ENUM ('campaign', 'ad_group', 'ad_item', 'keyword')
)
PARTITION BY LIST COLUMNS (resource_type) (
PARTITION campaigns VALUES IN ('campaign'),
PARTITION ad_groups VALUES IN ('ad_group'),
PARTITION ad_items VALUES IN ('ad_item'),
PARTITION keywords VALUES IN ('keyword')
);
不幸的是,这不起作用,因为据我了解,MariaDB 不支持枚举字段上的分区。我收到此错误:
字段“resource_type”属于此类分区不允许的类型
我尝试添加一个整数存储的生成列
partition_id
,但这也不起作用,因为根据我的理解,MariaDB 也不支持按生成列进行分区。这是我尝试过的:
DROP TABLE IF EXISTS test_performance_data;
CREATE TABLE test_performance_data
(
id INT AUTO_INCREMENT PRIMARY KEY,
resource_type ENUM ('campaign', 'ad_group', 'ad_item', 'keyword'),
partition_id INT GENERATED ALWAYS AS (
CASE
WHEN resource_type = 'campaign' THEN 1
WHEN resource_type = 'ad_group' THEN 2
WHEN resource_type = 'ad_item' THEN 3
WHEN resource_type = 'keyword' THEN 4
END
) STORED
)
PARTITION BY LIST (partition_id) (
PARTITION campaigns VALUES IN (1),
PARTITION ad_groups VALUES IN (2),
PARTITION ad_items VALUES IN (3),
PARTITION keywords VALUES IN (4)
);
这是我得到的错误:
(子)分区函数中不允许使用常量、随机或与时区相关的表达式
我真的很想将分区保留在数据库级别,这意味着如果我需要添加列,它将由数据库管理,而不是由应用程序管理。
我考虑过添加一个整数
partition_id
列,以及一个插入前和更新前触发器,根据枚举字段对其进行更新,但由于触发器的性能开销,我不确定这是一个好主意。
解决这个问题的最佳方法是什么?
PS:不确定是否相关,但就上下文而言,
resource_type
(与resource_id
列一起)用于在 Laravel 中建模多态关系。10.6.18-MariaDB-log
版本。
提前非常感谢您的回答。
ENUM
是一个转移注意力的话题。 PARTITION BY LIST
对性能几乎没有帮助。 最好有 composite 索引 starting 与 ENUM
(或其他数据类型)。 根据不同的查询,将 PK 安排为复合的可能也是有益的。
为了进一步讨论,请提供您希望分区帮助解决的查询、其他重要查询以及
CREATE TABLE
的其余部分。 (然后我可以建议一组索引来帮助查询。它可能涉及建议对 PRIMARY KEY
进行更改。)