2010-03-23 3 views
2

У меня есть таблица MySQL InnoDB со столбцом состояния. Статус может быть «выполнен» или «обрабатывать». По мере роста таблицы не более 1% значений статуса будет «обрабатывать», тогда как остальные 99,9% значений будут «сделаны». Это кажется отличным кандидатом на индекс из-за высокой избирательности для «обработки» (хотя и не для «сделанного»). Можно ли создать индекс для столбца состояния, который индексирует только значение «обработка»? Я не хочу, чтобы индекс тратил огромное количество индексации пространства «сделано».Индексирование только одного значения столбца MySQL

+0

Просто интересно, было бы проще преобразовать в бит столбца с именем «обработка», где значение будет либо «1», либо «0». Будет меньше пространства. (Если у вас более 2 статусов) –

+0

Хорошее предложение. На самом деле у меня есть более двух статусов, но я упростил это ради простоты. – BrainCore

+0

«но я упростил это ради простоты» - тогда все в порядке, если вы не упростили его по другой причине :-) – paxdiablo

ответ

3

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

Предполагая, что строки никогда не переключаться от done к processing, вот шаги, которые вы можете использовать:

  1. При создании записи, вставьте его в Processing таблицу с колонкой, установленной на processing.
  2. Когда все будет готово, установите столбец в done.
  3. Периодически подметайте таблицу Processing, перемещаясь done строки в таблицу Done.

Это последнее непросто. Вы можете выполнить вставку/удаление в транзакции, чтобы обеспечить ее правильную передачу, или вы можете использовать уникальный идентификатор, чтобы определить, был ли он уже перенесен, а затем просто удалить его с Processing (у меня нет опыта работы с поддержкой транзакций MySQL, поэтому я также предоставляя этот вариант).

Таким образом, вы только индексируете несколько из 99,9% строк done, которые еще не переданы в таблицу Done. Он также будет работать с несколькими состояниями processing, о которых вы указали в комментариях (записи передаются только тогда, когда они попадают в состояние done, все остальные штаты остаются в таблице Processing).

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

0

Лучшее решение: не используйте строки для указания статусов. Вместо этого используйте константы в вашем коде с дескриптивными именами => целочисленными значениями. Затем это целое число хранится в базе данных, а MySQL будет работать LOT быстрее, чем со строками.

Я не знаю, какой язык вы используете, но, например, в PHP:

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

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

вместо того, что у вас есть сейчас:

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

Спасибо за ответ.Строки на самом деле являются ENUM, что означает, что они отображаются на целые числа. Хотя ваше предложение действительно, оно не попадает в корень моего вопроса: нужно ли это, и если да, то как я могу индексировать только определенное значение в столбце? – BrainCore

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