Насколько неправильно иметь уникальный и обычный индексы в одном столбце?
-
08-07-2019 - |
Вопрос
У меня есть следующая структура таблицы
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 записей.
- Насколько плохо иметь уникальный и обычный индексы в одном и том же поле?
- Насколько плохо иметь индексы большего размера, чем данные, когда таблица состоит исключительно из идентификаторов?
Решение
Я полагаю, что если вы создали свой уникальный индекс как (user_id
, date_expired
, foreign_id
), вы получите то же преимущество от наличия нормального индекса на user_id
только с уникальным индексом.MySQL может использовать первые столбцы любого индекса для уменьшения количества строк в соединении таким же образом, как индекс на user_id
.
Видишь Документация по индексу MySQL для получения дополнительной информации.
Вы имеете в виду id
столбец auto_increment в другом месте вашей схемы для экономии места?Поскольку ваш уникальный индекс охватывает все остальные столбцы вашей таблицы, по сути, он сам по себе является первичным ключом и может быть удален, если вы этого не сделаете.
Вы можете проверить, какие ключи использует ваш запрос, добавив к нему префикс EXPLAIN (ОБЪЯСНЕНИЕ).
Другие советы
Я не понимаю, что вы подразумеваете под дублирующимися индексами.У вас есть три индекса в таблице:
- Один для первичного ключа 'id' (что подразумевает уникальность)
- Еще один уникальный для комбинации 'date_expired', 'user_id' и 'foreign_id'
- И третий только через 'user_id'
таким образом, дублирования нет, у вас есть три другой индексы, которые будут делать разные вещи.Вам нужен номер 3, чтобы ускорить запросы, связанные с user_id, который вы видите.Так что в этой конкретной таблице нет ничего плохого, вы ничего не дублируете.Что касается второго вопроса, это зависит от ваших потребностей, но, конечно, это не плохой чтобы в индексах было занято больше места, чем в данных.
Что было бы плохо, например, так это иметь UNIQUE ('user_id'), а позже КЛЮЧ ('user_id') (я даже не уверен, позволит ли MySQL это), потому что один индекс будет содержать другой, и ничего не выиграет.
Иметь несколько индексов, включая одно поле, совсем неплохо (по сути, они индексируют разные вещи).Это оказывает небольшое влияние на производительность записи, но это типичный компромисс, который у вас есть с каждым индексом на первом месте.Наличие индексов, занимающих больше места, чем сами данные, неплохо, если пространство дешевое.В вашем случае это должно быть дешево, учитывая тот факт, что у вас действительно небольшое количество записей.
Вопрос, который я бы задал на вашем месте, заключается в следующем:Как индексация такой маленькой таблицы так сильно влияет на время выполнения моего запроса?Возможно, вы делаете что-то неправильно (я думаю о множестве, возможно, избыточных запросов к этой таблице), поскольку ни один из них не должен находиться в пределах этого временного диапазона с таким небольшим количеством записей).