首页 > 解决方案 > Laravel softdeleteable 的 MySQL / MariaDB 分区(deleted_at IS NULL vs datetime value)

问题描述

Laravel Eloquent softdeleteable(有时称为softdeletable)表如下所示:

id | value1 | value2 | ... | valueN | deleted_at

并将deleted_at用于null活动条目和已删除条目的日期时间值。

将 InnoDB 表划分为活动记录和已删除记录是否可以实现/可取?

(意味着所有空值的分区和任何实际值的另一个分区)

更新:经过一番研究,这是我想出的分区:

ALTER TABLE `listings`
PARTITION BY RANGE( UNIX_TIMESTAMP(deleted_at) )
SUBPARTITION BY HASH( user_id )
SUBPARTITIONS 40
(
    PARTITION active VALUES LESS THAN (0), -- null values (not deleted rows) will go here
    PARTITION deleted VALUES LESS THAN MAXVALUE -- non-null values (deleted rows) will go here
);

更新 2:用户永远不会被软删除。房源会。他们最终会积累比活跃列表更多的已删除列表。用户可以在任何列中定义和组合任何数量的过滤器(以 excel 方式)。 user_iddeleted_at < 0(根据 将修剪分区而不会修剪IS NULLEXPLAIN PARTITIONS将始终出现在查询中。我认为分区总是会减少要检查的行数,有时查询会受益于使用剩余的索引之一。我不确定我是否正确。

标签: mysqlmariadbpartitioning

解决方案


PARTITIONing很少有助于提高性能。

这个

WHERE deleted_at IS NULL
  AND ...

将受益于综合指数:

INDEX(deleted_at, ...)

“...”部分以某种方式匹配的地方。

(请注意,这是有效的,因为IS NULL像 . 一样工作=。也就是说,这样的索引在说 时无济于事deleted_at IS NOT NULL这样在 . 中不会很有用deleted_at BETWEEN ... AND ...。)

向我们展示一些真实的查询;可能还有其他提示要分享。

不使用分区的索引:

PRIMARY KEY(user_id, id), -- perfect for finding one user
INDEX(id)   -- to keep auto_increment happy

如果user_id是唯一的,则完全摆脱id

您是否需要查找所有(或在其中搜索)已删除的用户?


推荐阅读