Як працює індексація баз даних? [зачинено]


2419

Зважаючи на те, що індексація настільки важлива, як набір даних збільшується в розмірі, чи може хтось пояснити, як працює індексація на рівні агностики бази даних?

Щоб отримати інформацію про запити щодо індексації поля, перегляньте, як індексувати стовпчик бази даних .

Відповіді:


3546

Для чого це потрібно?

Коли дані зберігаються на дискових пристроях зберігання даних, вони зберігаються у вигляді блоків даних. До цих блоків звертаються в повному обсязі, що робить їх атомним диском доступу. Дискові блоки структуровані приблизно так само, як і пов'язані списки; обидва містять розділ для даних, вказівник на розташування наступного вузла (або блоку), і обидва не повинні зберігатися безперервно.

Через те, що ряд записів можна сортувати лише за одним полем, ми можемо констатувати, що для пошуку в полі, яке не сортується, потрібен лінійний пошук, який вимагає N/2доступу до блоку (в середньому), де Nкількість блоків, які стіл охоплюється. Якщо це поле - це не ключове поле (тобто не містить унікальних записів), тоді слід шукати всю область таблицьN доступ до блоку.

Тоді як із відсортованим полем може використовуватися двійковий пошук, який має log2 N блок доступу. Оскільки дані відсортовані за не-ключовим полем, решту таблиці не потрібно шукати за дублюючими значеннями, як тільки буде знайдено більш високе значення. Таким чином, підвищення продуктивності є значним.

Що таке індексація?

Індексація - це спосіб сортування декількох записів за кількома полями. Створення індексу на полі в таблиці створює іншу структуру даних, яка містить значення поля та вказівник на запис, до якого він відноситься. Ця структура індексу потім сортується, що дозволяє виконувати Binary Searches на ній.

Недоліком індексації є те, що ці індекси потребують додаткового місця на диску, оскільки індекси зберігаються разом у таблиці за допомогою двигуна MyISAM, цей файл може швидко досягти обмежень розмірів базової файлової системи, якщо багато полів в одній таблиці індексуються .

Як це працює?

По-перше, накреслимо зразкову схему таблиці баз даних;

Назва поля Тип даних Розмір на диску
id (Первинний ключ) Непідписаний INT 4 байти
firstName Char (50) 50 байт
lastName Char (50) 50 байт
emailAddress Char (100) 100 байт

Примітка : замість варшара було використано char, щоб забезпечити точний розмір на значенні диска. Ця зразкова база даних містить п'ять мільйонів рядків і є нерозробленою. Тепер буде проаналізовано виконання декількох запитів. Це запит із використанням ідентифікатора (відсортоване ключове поле) та запиту, що використовує 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 наведена нижче;

Назва поля Тип даних Розмір на диску
firstName Char (50) 50 байт
(покажчик запису) Спеціальні 4 байти

Примітка . Покажчики в 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блокового доступу, далекий від 1 000 000 доступу до блоку, необхідного для пошуку відповідності firstName у неіндексованій таблиці.

Коли його слід використовувати?

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

Оскільки індекси використовуються лише для прискорення пошуку відповідного поля в записах, очевидно, що поля індексації, які використовуються лише для виводу, будуть просто марною витратою дискового простору та часу обробки при виконанні операції вставки або видалення, і таким чином слід уникати. З огляду на характер двійкового пошуку, важливість є унікальністю або унікальністю даних. Індексація на полі з кардинальністю 2 розділить дані навпіл, тоді як кардинальність 1000 поверне приблизно 1000 записів. При такій низькій кардинальності ефективність зводиться до лінійного сортування, і оптимізатор запитів уникне використання індексу, якщо кардинальність становить менше 30% від рекордної кількості, що фактично робить індекс марною витратою місця.


8
двійковий пошук можна здійснити, коли дані унікальні, я прав? хоча ви згадали, що важлива мінімальна кардинальність, алгоритм не був би простим двійковим пошуком, як би це наближення (~ log2 n) вплинуло на час процесу?
шампунь

9
@AbhishekShivkumar: Чудове запитання! Я думаю, що таблиця індексів матиме стільки рядків, скільки їх у таблиці даних. І оскільки це поле матиме лише 2 значення (булеве з true / false) і скажіть, що ви хочете записати зі значенням true, то ви можете лише вдвічі зменшити результат, встановлений у першому проході, у другому проході всі ваші записи мають значення true, тому є немає підстав для розмежування, тепер вам доведеться шукати таблицю даних лінійним способом, отже він сказав, що кардинальність слід враховувати під час вирішення індексованого стовпця. У цьому випадку індексувати на такий стовпець марно. Сподіваюся, що я маю рацію :)
Saurabh Patil

7
не повинно бути кількості доступу до блоку в середньому випадку (N+1)/2. Якщо ми підсумовуємо кількість доступів до блоку для всіх можливих випадків і ділимо його на кількість випадків, то у нас N*(N+1)/(2*n)це виходить (N+1)/2.
Адже

31
Я думаю, що у цій відповіді, наприклад, у реченні є кілька помилок друку: "далекий виклик від доступу 277,778 блоків, необхідних для неіндексованої таблиці". чи не означає автор 1 000 000 блокових доступу? 277,778 - кількість блоків, необхідних самим індексом. Здається, є і кілька інших неточностей :(
jcm

5
@jcm Він пояснив це в розділі "Що таке індексація" - "Індексація - це спосіб сортування кількох записів по декількох полях. Створення індексу на полі в таблиці створює іншу структуру даних, яка містить значення поля та покажчик до запису, до якого він відноситься. Ця структура індексу сортується, що дозволяє виконувати Binary Searches на ній. "
усмішка

293

Класичний приклад "Індекс у книгах"

Розгляньте «Книгу» на 1000 сторінок, розділену на 10 глав, кожен розділ зі 100 сторінок.

Просто, так?

Тепер уявіть, що ви хочете знайти конкретну главу, яка містить слово " Алхімік ". Без вказівної сторінки у вас немає іншого вибору, крім сканування всієї книги / глав. тобто: 1000 сторінок.

Ця аналогія відома як "Повне сканування таблиці" у світі баз даних.

введіть тут опис зображення

Але з індексною сторінкою ви знаєте, куди йти! І більше, щоб шукати будь-яку конкретну главу, яка має значення, вам потрібно щоразу переглядати сторінку індексів. Знайшовши відповідний індекс, ви зможете ефективно перейти до цієї глави, пропустивши решту.

Але тоді, крім фактичних 1000 сторінок, вам знадобиться ще ~ 10 сторінок, щоб показати індекси, тож загалом 1010 сторінок.

Таким чином, індекс - це окремий розділ, який зберігає значення індексованого стовпця + вказівника на індексований рядок у відсортованому порядку для ефективного пошуку.

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


23
дійсно приємна аналогія! смішно, я не зробив зв’язок між індексом книги та індексом db
Yolo Voe

2
Це змушує мене думати, Libraryчи не Grocery Store могли б ви уявити, що не має індексу в продуктовому магазині? Where's The Beef?!? Oh its next to the Restrooms, a mop, and makeup
JayRizzo

3
"Але з індексною сторінкою на початку, ви там." Що означає "ти там"?
фрісбетарій

2
Індекси зазвичай розташовуються внизу книг, тоді як зміст йде спереду. Але це робить аналогію ще кращою, оскільки порядок стовпців не має значення.
unrline

1
Твоє пояснення так легко прийняти. Інші люди, як правило, використовують складні терміни для пояснення речей. Я хотів би, щоб я міг дати більше одного внеску.
смарагдовий

240

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

З того часу я отримав деяке уявлення про мінус створення індексів: якщо ви записуєте в таблицю ( UPDATEабо INSERT) з одним індексом, у вас фактично дві операції запису у файловій системі. Один для даних таблиці та інший для даних індексу (і вдавання до них (і - якщо кластеризовано - вдавання даних таблиці)). Якщо таблиця та індекс розташовані на одному жорсткому диску, це коштує більше часу. Таким чином, таблиця без індексу (купи) дозволила б прискорити операції запису. (якби у вас було два індекси, ви закінчили б три операції запису тощо)

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

Інша проблема індексів - їх фрагментація з часом, коли дані вставляються. REORGANIZEдопомагає, ви повинні написати підпрограми, щоб це було зроблено.

У певних сценаріях купа корисніша, ніж таблиця з індексами,

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

Також досить важливою є диференціація між кластерними та некластеризованими індексами.

Допомогли мені: - Що насправді означають індекси кластеру та не кластеризованості?


3
Я думаю, що ці проблеми з індексацією можна вирішити, підтримуючи дві різні бази даних, як Master та Slave. Де Master можна використовувати для вставки або оновлення записів. Без індексування І раб можна використовувати для читання з правильним індексуванням правильно ???
бхаратеш

14
ні, неправильно, вибачте Необхідно оновлювати не тільки вміст таблиць, але й структуру індексу та вміст (b-дерево, вузли). Ваша концепція господаря і раба тут не має сенсу. що може бути здійсненним, хоча реплікація або дзеркальне відображення до другої бази даних, на якій відбувається аналітика, щоб зняти це навантаження від першої бази даних. ця друга база даних містила б копії даних та індекси цих даних.
Der U

3
Я ...! Спробуйте прочитати мій коментар і зрозуміти його правильно. Я також сказав те саме, я назвав master і slave (що завгодно) як "використання або дзеркальне відображення до другої бази даних, в якій проводиться аналітика, щоб зняти це робоче навантаження від першої бази даних. Ця друга база даних містила б копії даних і індекси на ці дані "
bharatesh

6
друга база даних - до якої здійснюється дзеркальне відображення або реплікація, підлеглий - зазнає всіх маніпуляцій з даними, як і перша. з кожною операцією dml індекси цієї другої бази даних відчуватимуть "ці проблеми індексації". Я не бачу виграшу в тому, де коли-небудь потрібні індекси та побудовані для швидкого аналізу, їх потрібно постійно оновлювати.
Der U

230

Індекс - це лише структура даних, яка прискорює пошук конкретного стовпця в базі даних. Ця структура зазвичай є b-деревом або хеш-таблицею, але це може бути будь-яка інша логічна структура.


29
+1 за мільйон разів на цю відповідь, як я знайшов цей список, намагаючись знайти просте пояснення, що таке індексація.
Джош Бурсон

1
Зауважимо, що "просто структура даних" не означає "додатково до даних". Деколи це (наприклад, "некластерний індекс"), а інколи визначає компонування даних (наприклад, "кластерний індекс").
Пабло Н

160

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

SELECT * FROM Employee 
WHERE Employee_Name = 'Abc'

Що було б без індексу?

Програмне забезпечення баз даних буквально повинно переглядати кожен рядок у таблиці Співробітник, щоб побачити, чи є ім'я Employee_Name для цього рядка "Abc". Оскільки ми хочемо, щоб кожен рядок із назвою 'Abc' знаходився всередині нього, ми не можемо просто перестати шукати, як тільки знайдемо лише один рядок із назвою 'Abc', тому що можуть бути інші рядки з назвою Abc . Отже, кожен рядок до останнього рядка потрібно шукати - це означає, що тисячі рядків у цьому сценарії доведеться вивчити в базі даних, щоб знайти рядки з назвою "Abc". Це називається скануванням повного столу

Як індекс бази даних може сприяти продуктивності

Весь сенс наявності індексу полягає в прискоренні пошукових запитів, по суті скорочення кількості записів / рядків у таблиці, які потрібно вивчити. Індекс - це структура даних (найчастіше це B-дерево), яка зберігає значення для певного стовпця в таблиці.

Як працює індекс B-дерев?

Причина B-дерев є найпопулярнішою структурою даних для індексів пов’язана з тим, що вони ефективні за часом - адже пошук, видалення та вставки можуть бути виконані в логарифмічний час. І ще одна основна причина B-дерев частіше використовується в тому, що дані, що зберігаються всередині B-дерева, можна сортувати. RDBMS, як правило, визначає, яка структура даних фактично використовується для індексу. Але в деяких сценаріях з певними RDBMS ви можете фактично вказати, яку структуру даних ви хочете використовувати у вашій базі даних під час створення самого індексу.

Як працює індекс хеш-таблиці?

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

Наприклад, запит, про який ми говорили раніше, може отримати користь від індексу хешу, створеного у стовпчику 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 є індекс, створений на ньому, база даних повинна буде вирішити, чи є насправді сенсом використання індексу для пошуку значень, які шукаються - тому що існують деякі сценарії, коли фактично менш ефективно використовувати індекс бази даних та ефективніше просто сканувати всю таблицю.

Яка вартість наявності індексу бази даних?

Він займає місце - і чим більша ваша таблиця, тим більший ваш індекс. Ще один хіт ефективності індексів - це той факт, що щоразу, коли ви додаєте, видаляєте або оновлюєте рядки у відповідній таблиці, ті самі операції потрібно буде робити з вашим індексом. Пам’ятайте, що індекс повинен містити ті самі мінімальні дані, що і те, що є в стовпцях (таблицях) таблиці, які охоплює індекс.

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

Дивись також

  1. Які колонки, як правило, мають хороші показники?
  2. Як працюють індекси бази даних

4
"індекс бази даних не зберігає значення в інших стовпцях" - неправда.
mustaccio

2
@mustaccio: Індекс зберігає посилання на рядок лише з індексованими стовпцями (наскільки я знаю). Я можу помилятися. Чи є у вас посилання, що говорить, що індекс зберігає значення інших стовпців?
Сомнат Мулук

3
@To Downvoters: Ви можете просто пояснити, що не так, щоб я міг покращитись?
Сомнат Мулук

2
Перевірте, наприклад, індекси кластеризації SQL Server або пункт DB2 CREATE INDEX ... INCLUDE. На мою думку, у вас є занадто багато узагальнень.
mustaccio

11
@mustaccio: Отже, за замовчуванням create indexне включаються інші стовпці і чому це слід. If we did just store all the other columns in the index, then it would be just like creating another copy of the entire table, which would take up way too much space and would be very inefficient.. Це більш узагальнена версія індексів. CREATE INDEX ... INCLUDE- це нова версія, враховуючи інші стовпці. Пост, який я пояснив, розглядає більш узагальнену версію. Як працюють індекси однієї книги, якщо врахувати всі бази даних? Чи не так? Як ви вважаєте, відповідь заслуговує на голосування?
Сомнат Мулук

96

Простий опис!

Індекс - це не що інше, як структура даних, яка зберігає значення для певного стовпця в таблиці. Індекс створюється на стовпчику таблиці.

Приклад: У нас є таблиця бази даних під назвою Userз трьома стовпцями - Name, Ageі Address. Припустимо, що Userтаблиця має тисячі рядків.

Скажімо, ми хочемо запустити запит, щоб знайти всі деталі користувачів, яких назвали "Джон". Якщо ми виконуємо наступний запит:

SELECT * FROM User 
WHERE Name = 'John'

Програмне забезпечення бази даних буквально повинно було б переглядати кожен ряд у Userтаблиці, щоб побачити, чи є Nameдля цього рядка "Джон". Це займе багато часу.

Тут indexнам допомагає: індекс використовується для прискорення пошукових запитів, по суті скорочення кількості записів / рядків у таблиці, яку потрібно вивчити .

Як створити індекс:

CREATE INDEX name_index
ON User (Name)

indexСкладається з значень стовпців (наприклад: Джон) з однієї таблиці , і ці значення зберігаються в структурі даних .

Тож тепер база даних використовуватиме індекс для пошуку співробітників на ім'я Джон, оскільки індекс, імовірно, буде відсортований за алфавітом за іменем Користувачі. І, оскільки воно сортоване, це означає, що пошук імені відбувається набагато швидше, тому що всі імена, що починаються на "J", будуть прямо поруч з індексом!


1
Індекс не означає порядок сортування на колонці
oligofren

4
Дякую. Це допомогло моєму розумінню. Отже, в основному індекс - це копія даних, що були відсортовані. Зазвичай дані стовпців у тому порядку, в якому вони були вставлені.
Ніл

34

Просто швидка пропозиція. Оскільки індексація коштує додаткового місця для запису та зберігання, тому, якщо вашій програмі потрібно більше операцій вставки / оновлення, можливо, ви хочете використовувати таблиці без індексів, але якщо вона потребує більше операцій пошуку даних, вам слід перейти до індексованих стіл.


6
Це коментар, а не відповідь.
RonJohn

5
Це більш помітно і, таким чином, більш корисно таким чином, оскільки це загальне зауваження. До якої відповіді це слід було б додати як коментар?
pfabri

1
ймовірно, коментар до ОП
гуярад

33

Просто подумайте про індекс бази даних як про індекс книги.

Якщо у вас є книга про собак і ви хочете знайти інформацію про, скажімо, німецьку вівчарку, ви, звичайно, можете перегортати всі сторінки книги і знаходити те, що ви шукаєте - але це, звичайно, займає багато часу і не дуже швидко.

Інший варіант полягає в тому, що ви можете просто перейти до розділу «Індекс» книги, а потім знайти те, що шукаєте, скориставшись назвою сутності, яку ви шукаєте (в даному випадку, німецької вівчарки), а також переглянувши номер сторінки, щоб швидко знайдіть те, що шукаєте.

У базі даних номер сторінки називається вказівником, який спрямовує базу даних до адреси на диску, на якому знаходиться об'єкт. Використовуючи ту саму аналогію німецької вівчарки, ми могли б мати щось подібне ("Німецька вівчарка", 0x77129), де 0x77129адреса на диску, де зберігаються дані про рядки для німецької вівчарки.

Коротше кажучи, індекс - це структура даних, яка зберігає значення для певного стовпця в таблиці, щоб прискорити пошук запитів.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.