仅索引一个MySQL列值

时间:2010-03-23 05:52:41

标签: mysql indexing innodb

我有一个带有状态列的MySQL InnoDB表。状态可以是“完成”或“处理”。随着表格的增长,最多.1%的状态值将是“处理”,而其他99.9%的值将“完成”。由于“处理”的高选择性(尽管不是“完成”),这似乎是一个很好的索引候选者。是否可以为状态列创建仅索引值“处理”的索引?我不希望索引浪费大量的空间索引“完成”。

2 个答案:

答案 0 :(得分:3)

我不知道有任何标准方法可以做到这一点,但我们之前通过使用两个表ProcessingDone解决了类似问题,前者带有索引,后者没有。

假设行不会从done切换回processing,以下是您可以使用的步骤:

  1. 创建记录时,请将其插入Processing表格,并将列设置为processing
  2. 完成后,将列设置为done
  3. 定期扫描Processing表,将done行移至Done表。
  4. 最后一个可能很棘手。您可以在事务中执行插入/删除以确保它正确传输,或者您可以使用唯一ID来检测它是否已经传输,然后将其从Processing中删除(我没有MySQL事务支持经验,这是为什么我也提供这个选项。)

    这样,您只会将99.9%done行中的一些行编入索引,而这些行尚未转移到Done表。它也适用于您在评论中提到的processing的多个状态(条目仅在它们达到done状态时被转移,所有其他状态都保留在Processing表中。

    这类似于将历史数据(永不改变的东西)转移到单独的表格以提高效率。它可能会使您需要访问done和非done行的某些查询复杂化,因为您必须加入两个表,因此请注意这是一种权衡。

答案 1 :(得分:0)

更好的解决方案:不要使用字符串来指示状态。而是在代码中使用带有描述性名称的常量=>整数值。然后,该整数存储在数据库中,并且MySQL将比使用字符串更快地工作。

我不知道您使用的语言,但例如在PHP中:

class Member
{
   const STATUS_ACTIVE = 1;
   const STATUS_BANNED = 2;
}

if ($member->getStatus() == Member::STATUS_ACTIVE)
{
}

而不是你现在拥有的:

if ($member->getStatus() == 'active')
{
}