Индекс ( англ. index ) - объект базы данных, который создан с целью повышения эффективности выполнения запросов. Таблицы в базе данных могут иметь большое количество строк, которые хранятся в произвольном порядке, и их поиск по заданному значению путем последовательного просмотра таблицы строка за строкой может занимать много времени. Индекс формируется из значений одного или нескольких столбцов таблицы и указателей на соответствующие строки таблицы и, таким образом, позволяет находить нужную строку по заданному значению. Ускорение работы с использованием индексов достигается в первую очередь за счет того, что индекс имеет структуру, оптимизированная для поиска - например, сбалансированного дерева. Некоторые СУБД расширяют возможности индексов введением возможности создания индексов по выражениям. Например, индекс может быть созданный по выражению upper (last_name) и соответственно будет хранить ссылки, ключом которых будут значения поля last_name в верхнем регистре. Кроме этого, индексы могут быть объявлении как уникальные так и не уникальны. Уникальный индекс реализует ограничения целостности на таблицы, исключая возможность вставки значений, которые повторяются.
Архитектура
Существует два типа индексов: кластерные и некластерный. В каждой таблице может быть только один кластерный индекс и многие некластерные. При присутствии кластерного индекса строки таблицы физически хранятся в заданном порядке и напрямую связаны с элементами индекса, благодаря чему значительно ускоряется доступ к данным при выполнении запросов, использующих данный индекс. Если в таблице нет кластерного индекса, таблица является неупорядоченной. Некластерный индекс, созданный для такой таблицы, содержащей лишь указатель на записи таблицы, в связи с чем при выборке необходимо по крайней мере еще одно обращение к диску для получения именно записи таблицы.
Индексы физически могут быть реализованы различными структурами. Наиболее часто B + деревья и хэш-таблицы.
Последовательность столбцов в составном индексе
Последовательность, в которой представлены столбцы в сложенном индексе, достаточно важна. Дело в том, что получить набор данных по запросу, затрагивающая лишь первый из проиндексированных столбцов, можно. Однако в большинстве СУБД невозможно или неэффективно получения данных только по второму и т.д. проиндексированным столбцам (без ограничений на первый).
Например, представим себе телефонный справочник, рассортированных сначала по городу, затем по фамилии, и затем по имени. Если вы знаете город, тогда вы легко можете найти все телефоны этого города. Однако в таком справочнике будет сложно найти все телефоны, записанные на определенное фамилия - для этого необходимо посмотреть в секцию каждого города и поискать там нужную информацию. Некоторые СУБД выполняют эту работу, другие же просто не используют такой индекс.
Эффективность
Для оптимальной эффективности запросов индексы обычно создаются на тех столбцах таблицы, которые часто используются в запросах. Для одной таблицы могут быть созданы несколько индексов. Однако увеличение числа индексов замедляет операции добавления, обновления, удаления строк таблицы, поскольку при этом необходимо обновлять сами индексы. Кроме этого индексы занимают дополнительный объем памяти, поэтому перед созданием индекса нужно удостовериться, что выигрыш, который планируется в эффективности запросов перевесит дополнительные затраты ресурсов компьютера на сопровождение индекса.
Ограничения
Индексы полезны для многих приложений, однако на их использование накладываются ограничения. Возьмем такой запрос SQL : SELECT first_name FROM people WHERE last_name = 'Франкенштейн';. Для выполнения такого запроса без индекса СУБД должна проверить поле last_name в каждой строке таблицы (этот механизм известен как «полный перебор» или «полный скан таблицы», в плане может отображаться словом «NATURAL»). При использовании индекса СУБД просто проходит по бинарном дереву, пока не найдет запись «Франкенштейн».Такой проход требует гораздо меньше ресурсов, чем полный перебор таблицы.
Теперь возьмем такой запрос: SELECT email_address FROM customers WHERE email_address LIKE '% @ yahoo.com';. Этот запрос должен нам найти всех клиентов, у которых е-мейл заканчивается на "@ yahoo.com», однако даже если по столбцу email_address является индекс, СУБД все равно будет использовать полный перебор таблицы. Это связано с тем, что индексы строятся в предположении, что слова / символы идут слева направо. Использование символа подстановки в начале условия поиска исключает для СУБД возможность использования поиска по бинарном дереву. Эта проблема может быть решена созданием дополнительного индекса по выражению reverse (email_address) и формированием запроса вида: select email_address from customers where reverse (email_address) like reverse ('% @ yahoo.com');. В этом случае символ подстановки окажется в наиболее правой позиции («moc.oohay%»), что не исключает использование индекса по reverse (email_address).