Индексы MySQL - сколько их достаточно?

Я пытаюсь настроить мой MySQL-сервер, чтобы проверить свои настройки, проанализировать журнал медленных запросов и, если возможно, упростить свои запросы.

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

Сколько индексов достаточно? Вы можете сказать, что это зависит от сотен факторов, но мне интересно, как я могу очистить свой mysql-slow.log достаточно, чтобы уменьшить нагрузку на сервер.

Кроме того, я увидел несколько "интересных" записей в журнале:

# Query_time: 0  Lock_time: 0  Rows_sent: 22  Rows_examined: 44
SELECT * FROM `categories` ORDER BY `orderid` ASC;

В рассматриваемой таблице содержится ровно 22 строки, индекс установлен в orderid. Почему этот запрос появляется в журнале? Зачем исследовать 44 строки, если он содержит только 22?

Ответы

Ответ 1

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

В вашем примере вы извлекаете все столбцы и только с 22 строками, и может быть быстрее просто выполнить сканирование таблицы и отсортировать их вместо использования индекса. Оптимизатор может/должен делать это и игнорировать индекс. Если это так, то индекс просто занимает пространство без каких-либо преимуществ. Если вы часто обращаетесь к вашей таблице "категории", вы можете захотеть закрепить ее в памяти, чтобы сервер db оставался доступным без необходимости переходить к диску все время.

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

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

Ответ 2

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

Например, если я обычно ищу пользователя по имени пользователя, я бы проиндексировал его, даже если идентификатор пользователя был основным ключом.

Ответ 3

Сколько индексов полностью зависит от запросов, которые вы выполняете, какие типы объединений выполняются (если есть), данные, хранящиеся в таблице, и насколько велики таблицы (а также многие другие факторы). Там действительно нет точной науки. Самый лучший инструмент в вашем арсенале для определения того, как оптимизировать запрос, - explain. Используя объяснение, вы можете узнать, какие соединения отсутствуют, какие возможные ключи могут быть использованы и какой ключ (если есть), а также количество строк, которые были проверены для каждой таблицы в соединении.

Используя эту информацию, вы можете решить, как закрепить свои таблицы и/или изменить свои запросы, чтобы сделать их более эффективными. Синтаксис для объяснения очень прост.

EXPLAIN SELECT * FROM `categories` ORDER BY `orderid` ASC;

Заметьте, объясните, что не выполняет запрос. Поэтому, если вы используете это для отладки запроса, для выполнения которого требуется 5 минут, объясните, что все еще будет очень быстро.

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

Ответ 4

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

Ответ 5

Индекс может ускорить запрос SELECT, но он замедлит запросы INSERT/UPDATE/DELETE, потому что им также нужно обновить индекс, а не только строку.

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

Ответ 6

Нет никакого магического числа для "наилучшего" количества индексов. Основное правило: добавить индексы для запросов, которые часто используются и/или должны выполняться быстро.

"слишком много" индексов не должно замедлять запросы, но каждый добавленный индекс добавляет небольшое количество времени для добавления/обновления элементов в db (так как он также изменяет индексы), и небольшое количество пространство. Однако, если вы просто добавляете индексы по мере необходимости, это, вероятно, не является большой проблемой.