Насколько неправильно иметь уникальный и нормальный индекс в одном столбце? - PullRequest
6 голосов
/ 15 ноября 2008

У меня следующая структура таблицы

CREATE TABLE `table` (
  `id` int(11) NOT NULL auto_increment,
  `date_expired` datetime NOT NULL,
  `user_id` int(11) NOT NULL,
  `foreign_id` int(11) NOT NULL,
  PRIMARY KEY  (`id`),
  UNIQUE KEY `date_expired` (`date_expired`,`user_id`,`foreign_id`),
  KEY `user_id` (`user_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

Как вы заметили, у меня есть дубликаты индексов user_id: date_expired & user_id. Мне, конечно, нужен уникальный индекс, потому что я хочу убедиться, что данные уникальны.

Причина дублирования индексов заключается в том, что без индекса user_id мой основной поисковый запрос занимает 4 секунды. С дополнительным индексом это занимает 1 секунду. Запрос присоединяется к таблице на user_id и проверяет date_expired.

В таблице всего 275 записей.

  • Насколько плохо иметь уникальный и нормальный индекс в одном поле?
  • Насколько плохо иметь индексы большего размера, чем данные, когда таблица является чисто идентификаторами?

Ответы [ 3 ]

8 голосов
/ 15 ноября 2008

Полагаю, если вы создали свой уникальный индекс как (user_id, date_expired, foreign_id), вы получите то же преимущество, что и обычный индекс на user_id только с уникальным индексом. MySQL может использовать первые столбцы любого индекса, чтобы сократить количество строк в соединении таким же образом, как индекс в user_id.

См. Документация индекса MySQL для получения дополнительной информации.

Вы ссылаетесь на столбец id auto_increment в другом месте вашей схемы, чтобы сэкономить место? Поскольку ваш уникальный индекс охватывает все другие столбцы в вашей таблице, он, по сути, сам по себе является первичным ключом и может быть отброшен, если вы этого не сделаете.

Вы можете проверить, какие ключи использует ваш запрос, добавив префикс EXPLAIN.

3 голосов
/ 15 ноября 2008

Я не понимаю, что вы подразумеваете под дублирующими индексами. У вас есть три индекса в таблице:

  1. Один для первичного ключа 'id' (что подразумевает уникальный)
  2. Еще один уникальный для комбинации 'date_expired', 'user_id' и 'foreign_id'
  3. И третий, только для user_id

так что дублирования нет, у вас есть три разных индекса, которые будут выполнять разные вещи. Вам нужен номер 3, чтобы ускорить запросы, связанные с user_id, который вы видите. Так что нет ничего плохого в этой конкретной таблице, вы ничего не дублируете. Что касается второго вопроса, то это зависит от ваших потребностей, но, безусловно, не 1013 * плохо иметь больше места в индексах, чем в данных.

Что было бы плохо, например, иметь UNIQUE ('user_id'), а затем KEY ('user_id') (я даже не уверен, разрешит ли это MySQL), потому что один индекс будет содержать другой и нечего приобретать.

1 голос
/ 15 ноября 2008

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

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

...