Как работает индексация базы данных?

Учитывая, что индексация настолько важна, что ваш набор данных увеличивается по размеру, может кто-нибудь объяснить, как индексирование работает на уровне агностики базы данных?

Информацию о запросах для индексации поля можно найти Как индексировать столбец базы данных.

1591
задан Xenph Yan 04 авг. '08 в 13:07
источник поделиться
10 ответов

Почему это необходимо?

Когда данные хранятся на дисковых накопителях, они хранятся в виде блоков данных. Доступ к этим блокам осуществляется целиком, что делает их доступным для атомарного доступа к диску. Блоки диска структурированы так же, как и связанные списки; оба содержат раздел для данных, указатель на расположение следующего node (или блока), и оба они не должны храниться смежно.

В связи с тем, что количество записей можно сортировать только в одном поле, мы можем заявить, что поиск в поле, которое не сортируется, требует линейного поиска, для которого требуется N/2 доступ к блокам (в среднем), где N - количество блоков, в которых находится таблица. Если это поле является неключевым полем (т.е. Не содержит уникальных записей), тогда все табличное пространство необходимо искать в N доступе к блоку.

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

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

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

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

Как это работает?

Во-первых, давайте нарисуем примерную схему таблицы базы данных;

Field name       Data type      Size on disk
id (Primary key) Unsigned INT   4 bytes
firstName        Char(50)       50 bytes
lastName         Char(50)       50 bytes
emailAddress     Char(100)      100 bytes

Примечание: char использовался вместо varchar, чтобы обеспечить точный размер на диске. Эта тестовая база данных содержит пять миллионов строк и не указана. Теперь будет проанализирована производительность нескольких запросов. Это запрос с использованием идентификатора (поля отсортированного ключа) и одного с использованием firstName (несимвольное несортированное поле).

Пример 1 - отсортированные или несортированные поля

Учитывая нашу примерную базу данных r = 5,000,000 записей фиксированного размера, дающих длину записи R = 204 байтов, и они хранятся в таблице с использованием механизма MyISAM, который использует размер блока по умолчанию B = 1,024 байт. Коэффициентом блокировки таблицы будет bfr = (B/R) = 1024/204 = 5 записей на блок диска. Общее количество блоков, необходимых для хранения таблицы, составляет N = (r/bfr) = 5000000/5 = 1,000,000.

Для линейного поиска в поле id потребуется среднее число N/2 = 500,000 для доступа к блоку, чтобы найти значение, учитывая, что поле id является ключевым полем. Но так как поле id также сортируется, может быть проведен двоичный поиск, требующий среднего из log2 1000000 = 19.93 = 20 доступа к блокам. Мгновенно мы видим, что это радикальное улучшение.

Теперь поле firstName не сортируется и не поле ключа, поэтому бинарный поиск невозможен, и значения не уникальны, и, следовательно, таблица потребует поиска до конца для точного доступа к блоку N = 1,000,000. Именно в этой ситуации индексирование направлено на исправление.

Учитывая, что индексная запись содержит только проиндексированное поле и указатель на исходную запись, разумно, что она будет меньше, чем многопольная запись, на которую указывает. Таким образом, для самого индекса требуется меньше блоков диска, чем исходная таблица, поэтому требуется меньше доступа к блокам для итерации. Схема для индекса в поле firstName приведена ниже;

Field name       Data type      Size on disk
firstName        Char(50)       50 bytes
(record pointer) Special        4 bytes

Примечание. Указатели в MySQL имеют длину 2, 3, 4 или 5 байтов в зависимости от размера таблицы.

Пример 2 - индексирование

Учитывая нашу примерную базу данных r = 5,000,000 записей с длиной записи индекса R = 54 байт и использованием размера блока по умолчанию B = 1,024 байт. Блокирующим фактором индекса будет bfr = (B/R) = 1024/54 = 18 записей на блок диска. Общее количество блоков, необходимых для хранения индекса, составляет N = (r/bfr) = 5000000/18 = 277,778.

Теперь поиск с использованием поля firstName может использовать индекс для повышения производительности. Это позволяет выполнять двоичный поиск индекса со средним значением доступа к блоку log2 277778 = 18.08 = 19. Чтобы найти адрес фактической записи, для которой требуется дополнительный доступ к блоку для чтения, приведение общего количества к 19 + 1 = 20 блочным доступам, далеко от 1000 000 запросов блоков, необходимых для поиска совпадения firstName в таблице без индексирования.

Когда он должен использоваться?

Учитывая, что для создания индекса требуется дополнительное дисковое пространство (277 778 дополнительных блоков из приведенного выше примера, увеличение на 28%), и что слишком много индексов могут вызывать проблемы, связанные с ограничениями размера файловой системы, следует тщательно подумать выберите правильные поля для индексации.

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

2477
ответ дан Xenph Yan 04 авг. '08 в 13:41
источник поделиться

В первый раз, когда я прочитал это, это было очень полезно для меня. Спасибо.

С тех пор я получил некоторое представление о недостатке создания индексов: если вы записываете в таблицу (UPDATE или INSERT) с одним индексом, у вас фактически есть две операции записи в файловой системе. Один для данных таблицы и другой для данных индекса (и его использование (и - если кластеризованное - использование табличных данных)). Если таблица и индекс расположены на одном жестком диске, это требует больше времени. Таким образом, таблица без индекса (кучи) позволит быстрее выполнять операции записи. (если у вас было два индекса, у вас было бы три операции записи и т.д.)

Однако определение двух разных мест на двух разных жестких дисках для данных индекса и табличных данных может уменьшить/устранить проблему увеличения стоимости времени. Это требует определения дополнительных групп файлов с соответствующими файлами на требуемых жестких дисках и определения местоположения таблицы/индекса по желанию.

Другая проблема с индексами - их фрагментация с течением времени при вставке данных. REORGANIZE помогает, вы должны написать процедуры, чтобы сделать это.

В некоторых сценариях куча более полезна, чем таблица с индексами,

например: - Если у вас есть много соперничающих записей, но только одно ночное чтение за пределами рабочего времени для сообщения.

Кроме того, дифференциация между кластерными и некластеризованными индексами весьма важна.

Помог мне: - Что действительно означает кластерный и некластеризованный индекс?

147
ответ дан Der U 30 апр. '13 в 17:31
источник поделиться

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

Для получения дополнительной информации я рекомендую следующее: Как работают индексы базы данных? И как помогают индексы?

91
ответ дан hcarreras 20 февр. '14 в 17:40
источник поделиться

Теперь скажем, что мы хотим запустить запрос, чтобы найти все сведения о любых сотрудниках, которые называются "Abc?

SELECT * FROM Employee 
WHERE Employee_Name = 'Abc'

Что произойдет без индекса?

Программное обеспечение базы данных в буквальном смысле должно смотреть каждую отдельную строку в таблице Employee, чтобы узнать, является ли Employee_Name для этой строки "Abc. И поскольку мы хотим, чтобы каждая строка с именем" Abc внутри нее ", мы не можем просто перестать смотреть, как только найдем только одну строку с именем" Abc ", потому что могут быть другие строки с именем Abc, Таким образом, каждая строка до последней строки должна быть найдена - это означает, что тысячи строк в этом сценарии должны быть проверены базой данных, чтобы найти строки с именем" Abc". Это то, что называется полным сканированием таблицы

Как индекс базы данных может помочь производительности

Весь смысл иметь индекс - ускорить поисковые запросы, существенно сократив количество записей/строк в таблице, которые необходимо изучить. Индекс представляет собой структуру данных (чаще всего это B-дерево), которая хранит значения для определенного столбца в таблице.

Как работает индекс B-деревьев?

Причина, по которой B-деревья являются самой популярной структурой данных для индексов, объясняется тем, что они эффективны во времени - потому что поиск, удаление и вставка могут выполняться в логарифмическом времени. И еще одна важная причина, по которой B-деревья чаще используются, заключается в том, что данные, которые хранятся внутри B-дерева, могут быть отсортированы. СУРБД обычно определяет, какая структура данных фактически используется для индекса. Но в некоторых сценариях с определенными СУБД вы можете указать, какую структуру данных вы хотите использовать в своей базе данных при создании самого индекса.

Как работает индекс таблицы хешей?

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

Например, запрос, который мы обсуждали ранее, может извлечь выгоду из хеш-индекса, созданного в столбце Employee_Name. Способ работы хэш-индекса будет состоять в том, что значение столбца будет ключом в хэш-таблице, а фактическое значение, сопоставленное этому ключу, будет просто указателем на данные строки в таблице. Поскольку хеш-таблица в основном представляет собой ассоциативный массив, типичная запись будет выглядеть примерно так: "Abc = > 0x28939", где 0x28939 - это ссылка на строку таблицы, где Abc хранится в памяти. Поиск значения типа "Abc" в индекс хеш-таблицы и возврат ссылки на строку в памяти, очевидно, намного быстрее, чем сканирование таблицы, чтобы найти все строки со значением "Abc" в столбце Employee_Name.

Недостатки хэш-индекса

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

Что именно находится в индексе базы данных? Итак, теперь вы знаете, что индекс базы данных создается в столбце в таблице и что индекс сохраняет значения в этом конкретном столбце. Но важно понимать, что индекс базы данных не сохраняет значения в других столбцах одной и той же таблицы. Например, если мы создаем индекс в столбце Employee_Name, это означает, что значения столбца Employee_Age и Employee_Address также не сохраняются в индексе. Если бы мы просто сохранили все остальные столбцы в индексе, то это было бы похоже на создание другой копии всей таблицы, которая занимала бы слишком много места и была бы очень неэффективной.

Как база данных знает, когда использовать индекс?Когда запускается запрос типа "SELECT * FROM Employee WHERE Employee_Name = 'Abc", база данных проверяет, есть ли индекс для столбца (ов), который запрашивается. Предполагая, что столбец Employee_Name имеет индекс, созданный на нем, база данных должна будет решить, действительно ли имеет смысл использовать индекс для поиска искомых значений - поскольку существуют некоторые сценарии, где на самом деле менее эффективно использовать индекс базы данных, и более эффективно просто сканировать всю таблицу.

Какова стоимость индекса базы данных?

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

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

См. также

62
ответ дан Somnath Muluk 13 авг. '16 в 21:36
источник поделиться

Простое описание!!!!!!!!!!

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

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

Теперь скажем, что мы хотим запустить запрос, чтобы найти все сведения о любых пользователях, названных "Джон". Если мы запустим следующий запрос.

SELECT * FROM User 
WHERE Name = 'John'

Программное обеспечение базы данных буквально должно было бы смотреть на каждую строку в таблице User, чтобы узнать, является ли Name для этой строки "John". Это займет много времени. Именно здесь индекс помогает нам "индекс используется для ускорения поисковых запросов, существенно сокращая количество записей/строк в таблице, которая должна быть проверена".
Как создать индекс

CREATE INDEX name_index
ON User (Name)

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

25
ответ дан ProgrammerPanda 02 авг. '16 в 4:30
источник поделиться

Классический пример "Индекс в книгах"

Рассмотрим "книгу" из 1000 страниц, разделенную на 100 разделов, каждый раздел с X-страницами.

Простой, да?

Теперь, без индексной страницы, чтобы найти конкретный раздел, который начинается с буквы "S", у вас нет другого выбора, кроме сканирования всей книги. i.e: 1000 страниц

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

Но тогда, кроме 1000 страниц, вам понадобится еще ~ 10 страниц, чтобы отобразить страницу индекса, поэтому полностью 1010 страниц.

Таким образом, индекс представляет собой отдельный раздел, который хранит данные индексированных записей в отсортированном порядке для эффективного поиска.

В школах все просто, не так ли?: P

20
ответ дан Sankarganesh Eswaran 23 апр. '17 в 17:43
источник поделиться

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

15
ответ дан mudasir 14 янв. '15 в 9:44
источник поделиться

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

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

9
ответ дан Alf Moh 21 дек. '16 в 20:16
источник поделиться

В реляционной базе данных, использующей хранилище строк, вторичный индекс хранится в отдельной области хранения вдали от "данных базовой таблицы". Когда вы создаете индекс, базовая таблица перемещается для извлечения индексируемых столбцов, которые вставляются в сохраненную структуру индексов - обычно это B-дерево - и сохраняются в постоянном хранилище для постоянных таблиц.

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

Когда строка вставлена, соответствующая строка записывается в индекс, а когда строка удаляется, ее строка индекса выводится.

Обратите внимание, что именно поэтому индексы занимают пробелы, и поэтому наличие большого количества индексов замедляет операции записи в базовой таблице: индексы должны храниться в синхронизации с таблицей, поэтому для каждого INSERT или DELETE для базовой таблицы, в индексах будет активность, а UPDATE в базовую таблицу - даже если обновленный столбец не находится в индексе - может вызвать активность индекса, а некоторые управляющие хранилища данных базы данных хранят смещения строк, которые могут потребоваться обновить.

Точное поведение зависит от реализации механизма хранения.

Некоторые механизмы хранения реализуют "первичные индексы", как правило, на PRIMARY KEY. Наиболее часто используемым механизмом хранения этого типа является MySQL InnoDB - в этом случае данные базовой таблицы хранятся в структуре B-Tree, а вторичные индексы сохраняют PRIMARY KEY для каждой строки. Oracle "Индексные упорядоченные таблицы" также реализованы таким образом.

Большим преимуществом этой структуры является поиск в PRIMARY KEY очень быстро, так как только одна структура должна быть посещена, чтобы вытягивать строки, а не два для традиционного хранилища "куча + вторичный индекс".

Есть много интересных вариантов индексов: "неполные" индексы, что означает индексы, которые загружаются только в том случае, если свойство выполнено (это полезно, если у вас есть огромная таблица, но обычно выполняется поиск по определенным значениям столбца), "основанный на функции" индексы, где значения индекса вычисляются по функции и т.д. PostgreSQL имеет много таких.

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

7
ответ дан halcosho 29 авг. '17 в 12:46
источник поделиться

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

0
ответ дан P.Thompson 20 окт. '17 в 10:49
источник поделиться

Другие вопросы по меткам