mariadb (mysql) 子分区错误(总子分区数超过 64)
mariadb (mysql) sub partition error (total sub partition count exceeds 64)
enter image description here
你好
我想配置一个分区(每月)/子分区(每天)作为上面的查询。
如果子分区总数超过64,
'(errno:168“来自引擎的未知(一般)错误”)'
由于错误,未创建 table。 (创建小于64成功)
我知道可以创建的最大分区数(包括子分区)是 8,192,有什么我遗漏的吗?
下面是日志table。
create table detection_log
(
id bigint auto_increment,
detected_time datetime default '1970-01-01' not null,
malware_title varchar(255) null,
malware_category varchar(30) null,
user_name varchar(30) null,
department_path varchar(255) null,
PRIMARY KEY (detected_time, id),
INDEX `detection_log_id_uindex` (id),
INDEX `detection_log_malware_title_index` (malware_title),
INDEX `detection_log_malware_category_index` (malware_category),
INDEX `detection_log_user_name_index` (user_name),
INDEX `detection_log_department_path_index` (departmen`enter code here`t_path)
);
SUBPARTITIONs
没有提供我所知道的好处。
HASH
分区要么没有好处,要么损害性能。
所以...解释一下您希望通过分区获得什么;然后我们可以讨论 any 类型的分区是否值得做。另外,提供可能的 SELECTs
,以便我们讨论最优的 INDEXes
。如果您需要“二维”索引,可能 表示需要分区(但仍然不是子分区)。
更多
我明白了PRIMARY KEY(detected_time,id)
。这提供了一种非常快速的方法
SELECT ...
WHERE detected_time BETWEEN ... AND ...
ORDER BY detected_time, id
事实上,它可能 比您也对 table 进行分区要快 。 (作为一般规则,在PK的第一部分进行分区是没有用的。)
如果需要的话
SELECT ...
WHERE user_id = 123
AND detected_time BETWEEN ... AND ...
ORDER BY detected_time, id
那么这是最优的:
INDEX(user_id, detected_time, id)
同样,可能比任何列上的任何形式的分区都快。
和
与 1000 行 table 相比,“点查询”(WHERE key = 123
) 在 10 亿行 table 中多花费几毫秒。差异很少是重要的。 BTree 的深度(可能是 5 层 vs 2 层)是主要区别。如果你 PARTITION
table,你可能会删除 BTree 的 1 或 2 层,但用代码替换它们以“修剪”到所需的分区。我声称这种权衡不会提供性能优势。
无论 table 大小如何,“范围查询”的速度几乎相同。这是因为该结构实际上是一个B+Tree,所以获取'next'行是非常高效的。
因此,在巨大 table上优化查询的主要目标是利用B+Tree的特性。
分页
SELECT log.detected_time, log.user_name, log.department_path,
log.malware_category, log.malware_title
FROM detection_log as log
JOIN
(
SELECT id
FROM detection_log
WHERE user_name = 'param'
ORDER BY detected_time DESC
LIMIT 25 OFFSET 1000
) as temp ON temp.id = log.id;
好的部分:查找 ID,然后获取数据。
慢的部分:使用OFFSET
。
有这个复合索引:INDEX(user_name, detected_time, id)
顺序。使用 department_path
.
时创建另一个索引
而不是 OFFSET
,“记住你离开的地方”。专门关于此的博客:http://mysql.rjweb.org/doc.php/pagination
正在清除
一年后删除是 PARTITIONing
的绝妙用法。使用 PARTITION BY RANGE(TO_DAYS(detected_time))
并有 ~55 个每周或 15 个每月的分区。有关详细信息,请参阅 HTTP://mysql.rjweb.org/doc.php/partitionmaint。 DROP PARTITION
比 DELETE
快得多。 (这个分区不会加速SELECT
。)
enter image description here
你好
我想配置一个分区(每月)/子分区(每天)作为上面的查询。 如果子分区总数超过64, '(errno:168“来自引擎的未知(一般)错误”)' 由于错误,未创建 table。 (创建小于64成功)
我知道可以创建的最大分区数(包括子分区)是 8,192,有什么我遗漏的吗?
下面是日志table。
create table detection_log
(
id bigint auto_increment,
detected_time datetime default '1970-01-01' not null,
malware_title varchar(255) null,
malware_category varchar(30) null,
user_name varchar(30) null,
department_path varchar(255) null,
PRIMARY KEY (detected_time, id),
INDEX `detection_log_id_uindex` (id),
INDEX `detection_log_malware_title_index` (malware_title),
INDEX `detection_log_malware_category_index` (malware_category),
INDEX `detection_log_user_name_index` (user_name),
INDEX `detection_log_department_path_index` (departmen`enter code here`t_path)
);
SUBPARTITIONs
没有提供我所知道的好处。HASH
分区要么没有好处,要么损害性能。
所以...解释一下您希望通过分区获得什么;然后我们可以讨论 any 类型的分区是否值得做。另外,提供可能的 SELECTs
,以便我们讨论最优的 INDEXes
。如果您需要“二维”索引,可能 表示需要分区(但仍然不是子分区)。
更多
我明白了PRIMARY KEY(detected_time,id)
。这提供了一种非常快速的方法
SELECT ...
WHERE detected_time BETWEEN ... AND ...
ORDER BY detected_time, id
事实上,它可能 比您也对 table 进行分区要快 。 (作为一般规则,在PK的第一部分进行分区是没有用的。)
如果需要的话
SELECT ...
WHERE user_id = 123
AND detected_time BETWEEN ... AND ...
ORDER BY detected_time, id
那么这是最优的:
INDEX(user_id, detected_time, id)
同样,可能比任何列上的任何形式的分区都快。
和
与 1000 行 table 相比,“点查询”(WHERE key = 123
) 在 10 亿行 table 中多花费几毫秒。差异很少是重要的。 BTree 的深度(可能是 5 层 vs 2 层)是主要区别。如果你 PARTITION
table,你可能会删除 BTree 的 1 或 2 层,但用代码替换它们以“修剪”到所需的分区。我声称这种权衡不会提供性能优势。
无论 table 大小如何,“范围查询”的速度几乎相同。这是因为该结构实际上是一个B+Tree,所以获取'next'行是非常高效的。
因此,在巨大 table上优化查询的主要目标是利用B+Tree的特性。
分页
SELECT log.detected_time, log.user_name, log.department_path,
log.malware_category, log.malware_title
FROM detection_log as log
JOIN
(
SELECT id
FROM detection_log
WHERE user_name = 'param'
ORDER BY detected_time DESC
LIMIT 25 OFFSET 1000
) as temp ON temp.id = log.id;
好的部分:查找 ID,然后获取数据。
慢的部分:使用OFFSET
。
有这个复合索引:INDEX(user_name, detected_time, id)
顺序。使用 department_path
.
而不是 OFFSET
,“记住你离开的地方”。专门关于此的博客:http://mysql.rjweb.org/doc.php/pagination
正在清除
一年后删除是 PARTITIONing
的绝妙用法。使用 PARTITION BY RANGE(TO_DAYS(detected_time))
并有 ~55 个每周或 15 个每月的分区。有关详细信息,请参阅 HTTP://mysql.rjweb.org/doc.php/partitionmaint。 DROP PARTITION
比 DELETE
快得多。 (这个分区不会加速SELECT
。)