Що означає "індекс" на RDBMS? [зачинено]


21

Я використовую індекси, як це робить більшість розробників (здебільшого на ... ну! Індекс), але я впевнений, що існує багато тонких способів оптимізації бази даних за допомогою індексу. Я не впевнений, чи він специфічний для будь-якої реалізації СУБД.

Моє запитання: які хороші приклади використання індексу (крім основних, очевидних випадків), і як СУБД оптимізує свою базу даних, коли ви вказуєте індекс на таблиці?


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

Мені подобається пояснювати індекси за допомогою метафори бібліотеки mysqlperformanceblog.com/2011/08/30/… Подивіться, чи це допомагає ..
Джонатан

Відповіді:


11

Подумайте про індекс як "зміст" ... це впорядкований список покажчиків на позиції у файлі, також зсуви. Скажіть, що у вас зберігаються мільйони записів у таблиці, а не шукайте таблицю для відповідності критеріям, набагато швидше посилатись на упорядкований список на відповідність, а потім укладати покажчики на конкретні відповідні рядки. Ідеальним прикладом індексу є поле первинного ключа таблиць, найчастіше його поле "id". Якщо ви хочете ідентифікатор рядка # 11234566, набагато швидше запитати покажчик на вказівник на дані, ніж сканувати джерело даних на позицію 11234566.

Ось не настільки очевидне використання індексації:

CREATE TABLE activity_log (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
activity_type_id SMALLINT UNSIGNED NOT NULL,
datetime_created DATETIME
KEY(activity_type_id),
PRIMARY KEY(id)
);
CREATE TABLE activity_log_to_date_key (
activity_log_id INT UNSIGNED NOT NULL,
date_created_key  INT UNSIGNED NOT NULL REFERENCES dim_datetime(id),
UNIQUE KEY(activity_log_id),
KEY(date_created_key)
);
CREATE TABLE dim_datetime (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
date_hour DATETIME NOT NULL,
PRIMARY KEY(id),
KEY(date_hour)
);

Ваша операція може створити ваш запис журналу, але потім створити посилання на індексований час дати, який буде швидше шукати / сортувати, ніж ваша таблиця журналів. Потім приєднайтеся до своєї таблиці журналів за власним первинним ключем. Якщо вам потрібно, щоб я розширив це питання, дайте мені знати. Сподіваюся, це має сенс.

Зразок запиту:

SELECT a.activity_log_id, al.activity_type_id, al.datetime_created
FROM activity_log_to_date_key a 
INNER JOIN dim_datetime d ON (d.id = a.date_created_key)
LEFT JOIN activity_log al ON (al.id = a.activity_log_id)
WHERE d.date_hour BETWEEN '2009-01-01 00:00:00' AND '2009-06-01 12:00:00';

дякую, це дуже зрозуміло! У вашому прикладі, чи "PRIMARY" змінить спосіб RDMBS зберігає "зміщення", або він просто використовується для обмежень унікальності?
Томас Жулін

9

Один момент, який, здається, багато людей пропускає, - це те, що СУБД часто (або може лише) використовувати лише один індекс на таблицю в запиті, і якщо він може і не використовувати декілька індексів, можливо, буде швидше використовувати комбінований індекс, якщо він присутній.

Наприклад, якщо шукати велику таблицю для рядків, WHERE AnIntegerColumn = 42 AND AnOtherInt = 69найшвидший маршрут до цих рядків буде індексом у двох стовпцях AnIntegerColumn та AnOtherInt. Якщо у вас є лише індекс для кожного окремо, але немає комбінованого індексу, БД буде шукати той чи інший індекс та окремо фільтрувати результати за допомогою другого пункту, або сканувати обидва та скасовувати результати згодом.

Ще одна поширена проста операція, яку можна вдосконалити за допомогою складених індексів, це WHERE SomeColumn = <SomeValue> ORDER BY SomeOtherColumn- якщо є індекс на SomeColumn та SomeOtherColumn (у правильному порядку), операції фільтрації та замовлення можуть бути виконані одночасно за певних обставин.

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


2

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


Щоб додати відповідь Гаурава, використовуйте "ПОЯСНИТИ РОЗШИРЕНИЙ", а потім негайно введіть "ПОКАЗАТИ ПОПЕРЕДЖЕННЯ", щоб побачити, як перекладається ваш запит.
випадковий стан

1

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


Це було правдою, але в наші дні ми говоримо, що не намагайтеся вдруге відгадати вашу підсистему вводу / виводу. Ви не знаєте, куди все-таки збирається масив пам’яті.
Гай

1
@gaius Я скоріше мав на увазі, якщо у вас не було налаштування RAID5 (тощо), поставити індекси на E :, дані на F:, тощо
jcolebrand
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.