2010-03-23 41 views
2

我有一个MySQL InnoDB表和一个状态列。状态可以是“完成”或“处理”。随着表格的增长,至多有1%的状态值将被“处理”,而另外99.9%的值将被“完成”。由于“处理”的高度选择性(尽管不适用于“完成”),这似乎成为索引的理想候选者。是否有可能为状态列创建一个只索引值“处理”的索引?我不希望索引浪费大量的空间索引“完成”。只索引一个MySQL列值

+0

只是想知道是否可以更容易地将其转换为名为“processing”的位列,其值为“1”或“0”。会使用更少的空间。 (除非你有更多的2个状态) – 2010-03-23 05:56:42

+0

好的建议。我其实有两个以上的状态,但为了简单起见,我简化了它。 – BrainCore 2010-03-23 05:59:01

+0

“但为了简单起见,我简化了它” - 那没问题,只要你没有为其他原因而简化它:-) – paxdiablo 2010-03-23 06:14:44

回答

3

我不知道的任何标准方式要做到这一点,但我们通过使用两个表ProcessingDone解决了类似的问题,前者用索引,后者不用。

假设行永远不要从done切换回processing,这里是您可以使用步骤:

  1. 当你创建一个记录,将其插入到Processing表设置为processing列。
  2. 完成后,将列设置为done
  3. 定期扫描Processing表,将done行移动到Done表。

最后一个可能会很棘手。你可以在事务中进行插入/删除操作,以确保它正确传输,或者你可以使用唯一的ID来检测它是否已经被传输,然后从Processing中删除它(我没有MySQL事务支持的经验,这就是为什么我也给这个选项)。

这样,您只能索引done行的99.9%中的几个,这些行尚未转移到Done表中。它也将与您在评论中暗示的processing的多个状态一起使用(条目仅在它们遇到done状态时转移,所有其他状态停留在Processing表中)。

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

0

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

我不知道你用什么语言,但例如在PHP:

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

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

,而不是你有什么现在:

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

感谢您的回答。这些字符串实际上是ENUM,这意味着它们被映射为整数。虽然你的建议是一个有效的建议,但它并没有达到我的问题的根源:是否有必要,如果是这样,我如何仅索引列中的特定值? – BrainCore 2010-03-23 06:03:15