我不是
MySQL专家.我的重点是Oracle,但我一直在使用分区多年,我发现你的建议用途非常合适,但不是主流对分区的理解.
低基数列的索引
暂且不谈索引合并.假设您的活动行有点分散,并且与非活动行数的比率为1:20.假设您的页面大小为8Kb,每个块大约需要20行.如果您获得非常均匀的isactive记录分布,那么每个块几乎会有1个.读取表中的每个块/页面的全表扫描将比使用索引查找相同的行要快得多.
所以我们说它们集中而不是均匀分散.即使它们集中在20%的页面甚至10%的页面中,即使在这些情况下,全表扫描也可以执行索引.
所以现在包括索引合并.如果在扫描ISactive的索引之后并且您没有访问该表但是将这些结果加入到另一个索引的结果中,并且最终结果集将产生读数,例如,小于块的5%.然后是,并且isactive和索引合并的索引可能是一个解决方案.
需要注意的是,MySQL中索引连接的实现存在很多限制.确保这适用于您的情况.但是你说你还有20个可以搜索的字段.因此,如果您没有为所有这些索引编制索引,以便有可用的第二个索引来加入IsActive索引,那么您将不会使用索引合并/连接.
对低基数列进行分区
现在,如果你对该列进行分区,那么你将拥有5%的IsActive = True的块,并且它们将被密集打包.完整分区扫描将快速生成活动记录列表,并允许将每个其他谓词应用为过滤器而不是索引搜索.
但那个标志发生了变化,对吧.
在Oracle中,我们有一个允许我们启用行迁移的命令.这意味着,当Is_Active从True更改为False时,移动该行所在的分区.这非常昂贵,但只比索引维护时更多,如果您索引该列而不是通过它进行分区.在分区示例中. Oracle首先使用更新更改行,然后执行删除操作,然后执行插入操作.如果您为该列编制索引,则会对该行进行更新,然后删除TRUE的索引条目,然后创建False的索引条目.
如果MySQL没有行迁移,那么你必须对你的crud包进行编程才能做到这一点. UPDATE_ROW_ISACTIVE(pk IN number)程序< ----类似的东西)将执行删除并为您插入. 关于Konerak的答案 虽然我同意并行访问是分区的一种用法,但它并不是唯一的.但是,如果您按照他提供的链接,页面最底部的用户评论是:
Beware of having low selectivity indexes on your table. A complex AND/OR WHERE clause will surely make your query very very slow if Index_Merge optimization is being used with an intersect() algorithm.
这似乎与你的情况有关,所以你可以接受FWIW的评论.