2009-12-30 5 views
1

Я создаю таблицу MySQL в Rails, которая имеет около 170 логических полей, каждая из которых должна быть доступна для поиска и, следовательно, индексирована, но когда я создаю индексы, я получаю сообщение об ошибке:Ошибка MySQL «Слишком много ключей»

To many keys specified; max 64 keys allowed 

Является ли этот предел жестко закодированным или есть переключатель конфигурации, который я могу перевернуть, который wold обойдет вокруг него?

Или мне нужно реорганизовать стол? Очевидный способ для меня выглядит объединить несколько таблиц вместе и выполнить запрос, такие как

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

Есть ли производительность и другие подводные камни с такой стратегии?

+3

Я * чрезвычайно * любопытно узнать, что потребует 170 булевых полей, подобных этому ... –

+0

Я * чрезвычайно * любопытно узнать, что такое предикат * такой таблицы. –

ответ

1

Классифицировать булевые поля в группы и поддерживать отдельные таблицы для этих групп. Сделайте запрос в свой запрос для получения результатов. Используйте EXPLAIN EXTENDED SELECT, чтобы оптимизировать индексы для ваших запросов.

Кроме того, попробуйте сохранить индексы покрытия, потому что MySQL использует только один индекс для каждой таблицы.

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

EDIT 01:

Как Даниил отметил в своем ответе, индекс cardianality для булевых значений не собирается, чтобы помочь вам каким-либо образом. Иногда ситуация становится хуже, если вы используете индекс для таких столбцов.

Вместо использования 170 булевых столбцов вы можете использовать 170 таблиц со ссылкой на первичный ключ родительских данных.

Предположим, что ваша родительская таблица students, а первичный ключ - student_id.

У вас есть отдельные столы для 170 предметов, которые они берут на себя в школьный возраст.

Если студент успешно передает английский предмет в своей форме 1, вставьте соответствующий student_id в таблицу form_1_english. Таким образом, у вас есть только уникальные значения в этом столбце, и индекс в этом столбце будет намного более эффективным.

+0

Спасибо Nirmal, это выглядит как очень аккуратная идея для рефакторинга. –

2

По-видимому, единственный способ сделать это на данный момент - увеличить значение MAX_KEY в исходном коде и перекомпилировать MySQL. (Source)

Или мне нужно реорганизовать стол?

Возможно, да. В дополнение к проблеме многих ключей индексирование булевых столбцов не особенно полезно. Индексы B-дерева наиболее эффективны для данных с высокой производительностью (т. Е. Столбцы со многими возможными значениями, где данные в столбце уникальны или почти уникальны).

Если вам нужно придерживаться этого дизайна, я думаю, вы можете подумать о том, чтобы оставить булевы столбцы без индексации и без ограничений внешнего ключа.

2

Другая альтернатива - хранить ваши булевы как битовые флаги в поле чисел.

например. вместо четырех полей «true», «false», «false», «true» сохраняют одно число «9» (1001 в двоичном формате).

+0

Я согласен, что битовые флаги прекрасны для некоторых приложений. Но насколько эффективно искать внутри флагов бит для определенного коммутатора? – Nirmal

+0

Не очень эффективно. Все зависит от того, будут ли столы содержать 100 строк или 100 тыс. –

Смежные вопросы