MySQL - почему бы не проиндексировать каждое поле?

107

Недавно я узнал о чудесах индексов, и производительность значительно улучшилась. Однако, несмотря на все, что я узнал, я не могу найти ответа на этот вопрос.

Индексы - это здорово, но почему нельзя просто проиндексировать все поля, чтобы сделать таблицу невероятно быстрой? Я уверен, что есть веская причина не делать этого, но как насчет трех полей в таблице из тридцати полей? 10 из 30? Где провести черту и почему?

Ваэль Виктус
источник
7
попробуйте вставить значение в таблицу с более чем 10 тыс. записей, которые проиндексированы, все записи должны быть обновлены из-за вставок / удаления, и это огромные накладные расходы времени и некоторые накладные расходы памяти, если каждое значение имеет индекс
Хесус Рамос,
5
Помимо пространства и производительности записи есть еще одна причина: использование нескольких индексов для доступа к одной таблице очень неэффективно . Это означает, что даже если у вас есть один индекс для каждого столбца, производительность выбора не очень хорошая, если доступ к нескольким столбцам осуществляется в предложении WHERE. В этом случае лучше всего использовать индекс с несколькими столбцами.
Маркус Винанд
1
если у вас есть таблица с 30 полями, вам действительно стоит взглянуть на свои структуры таблицы. С ними должно быть очень сложно работать.
Вебсайт

Ответы:

123

Индексы занимают место в памяти (RAM); Слишком много или слишком большое количество индексов, и БД придется переставлять их на диск и с диска. Они также увеличивают время вставки и удаления (каждый индекс должен обновляться для каждой вставки / удаления / обновления данных).

У вас нет бесконечной памяти. Сделать так, чтобы все индексы поместились в ОЗУ = хорошо.

У вас нет бесконечного времени. Индексирование только тех столбцов, которые вам нужно проиндексировать, минимизирует снижение производительности при вставке / удалении / обновлении.

Брайан Роуч
источник
11
Хороший случайный ответ, чтобы дать общее представление, но не очень помогает в фактическом определении, где провести черту по индексам. Как ты можешь знать? Просто добавьте их в часто встречающиеся поля WHERED и надейтесь на лучшее?
Эндрю
@ Андрей, полтора года спустя, ты нашел ответ на свой вопрос?
Sinjai
1
@Sinjai Добавление их к обычно используемым столбцам - хорошее практическое правило. Но иначе вы могли бы много читать, оказывается, если вы хотите стать экспертом по индексам. например. stackoverflow.com/questions/3049283/…
Эндрю
Не забывайте о дисковом пространстве.
jpmc26 02
27

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

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

AndyMac
источник
6
Ссылка предназначена для MS SQL Server ; этот вопрос для MySQL
OMG Ponies
5
@OMG: большинство пунктов в ссылке относится ко всем основным СУБД
RichardTheKiwi
5
@Richard aka cyberkiwi: Индексы не охватываются ANSI - чудо, что каждый производитель использовал похожую терминологию. Но даже в этом случае только SQL Server и MySQL используют терминологию «кластерный» и «некластеризованный» индекс - в SQL Server это означает больше, чем в MySQL. Нет никаких гарантий, что рекомендации одного поставщика применимы к другому.
OMG Ponies
3
@omg первые 6 баллов относятся к любым dbms. пропустите некластеризованные, затем ниже приведены другие моменты, касающиеся общей индексации, также по пункту. Если у вас есть конкретные вещи, на которые вы хотите указать, позвоните им. В противном случае похоже, что вы отрицаете все ответы, которые из комментариев (включая ваш удаленный ответ), что никто не согласен с вашей оценкой.
RichardTheKiwi
10

Вы должны сбалансировать потребности CRUD. Запись в таблицы становится медленной. Что касается того, где провести черту, это зависит от способа обращения к данным (сортировка, фильтрация и т. Д.).

Смандоли
источник
а также каждый индекс занимает некоторое место в базе данных
Acanthus
@Acanthus: самые маленькие жесткие диски измеряются в гигабайтах .
OMG Ponies
4
@OMG, но не RAM, как указывает Брайан. это не никогда хорошая идея , чтобы хранить больше , чем нужно. кэширование данных / индексов в ОЗУ, резервные носители (версии, которые подходят для каждой ленты и т. д.) - все это осуществляется бесполезными индексами
RichardTheKiwi
9
Изобилие ресурса - не причина для расточительства или неэффективности.
Smandoli
6
Верно, но ограничения не те, что были 10+ лет назад.
OMG Ponies
2

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

Лайонел Джериньо
источник
2

этот ответ основан на моем личном мнении, я использую свою математическую логику, чтобы ответить

второй вопрос был о границе, где остановиться. Сначала позвольте выполнить некоторые математические вычисления, предположим, что у нас есть N строк с L полями в таблице, если мы проиндексируем все поля, мы получим L новых индексных таблиц, где каждая таблица будет отсортирована в содержательно данные поля индекса, на первый взгляд, если ваша таблица имеет вес W, он станет W * 2 (1 тера станет 2 тера), если у вас есть 100 больших таблиц (я уже работал в проекте, где номер таблицы был arround 1800 table) вы потратите в 100 раз больше этого места (100 тера), это далеко не разумно.

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

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

что индексировать?

внешние ключи: обязательно на основе

первичный ключ: я еще не уверен, может быть, если кто-то прочитает это, может помочь в этом случае

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

из этих 3 пунктов я могу сделать вывод, что если у нас есть L полей, состоящих из K ключей, предел должен быть где-то около ((L-K)/2)+KL / 10

этот ответ основан на моей логике и личных ценах

Мохаммед Хуссейн Талеб
источник
1

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

Рашид Сакара
источник
Я не уверен, что это сделает чтение таблицы молниеносным, особенно если таблица данных составляет всего 100 МБ, а index.table 300 МБ или более.
Дэвид
Все, что вы сказали, было сказано ранее.
Vael Victus 09