2009-12-30 118 views
1

我在Rails中创建了一个具有大约170个布尔字段的MySQL表,每个表都需要被搜索并因此编入索引,但是当我创建索引时,我收到错误消息:MySQL'太多密钥'错误

To many keys specified; max 64 keys allowed 

这是限制硬编码还是有配置开关我可以翻转哪一个沃尔德绕过它?

或者我需要重构表吗?对我来说最显而易见的方法看起来是联合多个表和运行这样一个查询作为

Table.find.all(:conditions => "join1.fieldx = true and join2.fieldy = true") 

是否有任何性能或其他陷阱这样的战略?

+3

我非常*好奇地知道需要170个布尔字段吗? – 2009-12-30 11:43:12

+0

我很*好奇地知道这个表的*谓词是什么。 – 2009-12-30 12:00:53

回答

1

将布尔字段分类为组,并为这些组维护单独的表。在您的查询中加入连接以检索结果。使用EXPLAIN EXTENDED SELECT来优化查询的索引。

此外,请尝试维护覆盖索引,因为MySQL每个表只使用一个索引。

http://www.mysqlperformanceblog.com/2009/06/05/a-rule-of-thumb-for-choosing-column-order-in-indexes

编辑01:

正如丹尼尔在他的回答中提到,布尔值,指数cardianality是不会帮你的任何方式。在某些情况下,当您为这些列使用索引时会变得更糟。

代替使用170个布尔列,则可以使用170个表参照父数据的主键。

假设您的父表为students,主键为student_id

有170个科他们在学龄进行单独的表。

如果学生成功通过表格1中的英语科目,请在form_1_english表中插入相应的student_id。这样,您在该列中只有唯一的值,并且该列上的索引将更加高效。

+0

感谢Nirmal,这对于重构来说看起来非常整齐。 – 2009-12-30 17:01:23

2

显然目前唯一的方法是在源代码中增加MAX_KEY的值并重新编译MySQL。 (Source

或者我是否需要重构表?

可能是的。除了许多键的问题之外,索引布尔列并不是特别有利的。对于高基数数据(即具有许多可能值的列,其中列中的数据是唯一的或几乎唯一的),B树索引是最有效的。

如果你必须坚持这个设计,我想你可能要考虑离开布尔列非索引,没有任何外键约束。

2

另一种选择 - 存储您的布尔在许多领域的位标志。

例如而不是四个字段“真,假,假,真”存储一个数字“9”(二进制1001)。

+0

我同意位标志对于某些应用程序来说很棒。但是在特定开关的位标志内搜索效率如何? – Nirmal 2009-12-30 12:16:23

+0

效率不高。这一切都取决于表格将保持100行,还是100k。 – 2009-12-30 12:18:29