Индексы базы данных

Tweet

Рано или поздно каждый разработчик сталкивается с ситуацией, когда сайт "падает" и его приходится "поднимать". Причин тому может быть множество, в данной записи мы рассмотрим как применяется одно из лекарств для повышения производительности Drupal - а именно - ИНДЕКСЫ.

Что такое индексы?

Индексы применяются для быстрого поиска строк с указанным значением одного столбца. Без индекса чтение таблицы осуществляется по всей таблице, начиная с первой записи, пока не найдены соответствующие строки. Чем больше таблица, тем больше накладные расходы. Если же таблица содержит индекс по рассматриваемым столбцам, то MySQL может быстро определить позицию для поиска в середине файла данных без просмотра всех данных. Для таблицы, содержащей 1000 строк, это будет как минимум в 100 раз быстрее по сравнению с последовательным перебором всех записей. Однако в случае, когда необходим доступ почти ко всем 1000 строкам, быстрее будет происходить последовательное чтение, так как в его случае не требуется операций поиска по диску (источник).

Рассмотрим на очень простом примере. Допустим у нас есть такая вот вюшка: 

которая сгенерировала такой запрос:

SELECT users.uid AS uid, users.name AS users_name, users.created AS users_created FROM users users ORDER BY users_created DESC

Специально рассматриваем упрощенный вариант, с тем чтобы разобраться в базисе. 

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

И так будет повторяться каждый раз, когда вызывают запрос.

Создаем индекс: 

mysql> CREATE INDEX my_user_created ON users (users_created, users_name, users.uid));

Система создаст некую "копию таблицы", в которой данные будут указаны в порядке  "users_created, users_name, users.uid". Теперь, при выполнении запроса, системе не надо будет сортировать данные, а просто понадобится выдать содержимое индекса.

В случае запроса:

SELECT users.uid AS uid, users.name AS users_name, users.created AS users_created FROM users users WHERE uid BETWEEN 1 AND 12 ORDER BY users_created DESC

надо создавать индекс:

mysql> CREATE INDEX my_user_uid ON users (users.uid, users_created, users_name));

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