Ответ
Индексы ускоряют операции чтения (SELECT), но создают дополнительные затраты на запись, так как СУБД должна поддерживать их структуру в актуальном состоянии.
Причины снижения производительности при записи:
- Дополнительные операции ввода-вывода (I/O): При каждой модификации данных в таблице СУБД должна также обновить все связанные индексы. Каждый индекс — это отдельная структура данных (чаще всего B-дерево), запись в которую требует дисковых операций.
- Увеличение нагрузки на CPU: Необходимо вычислить новые значения ключей для индексов и найти правильное место для их вставки/удаления в структуре индекса.
- Фрагментация и балансировка: Частые обновления могут приводить к фрагментации страниц индекса и необходимости ребалансировки B-дерева, что является ресурсоемкой операцией.
- Блокировки: Обновление индекса может требовать захвата дополнительных блокировок, увеличивая конкуренцию между параллельными транзакциями.
Пример накладных расходов:
-- Предположим, в таблице `users` есть индекс по полю `email`.
INSERT INTO users (name, email, created_at) VALUES ('Alice', 'alice@example.com', NOW());
Что происходит внутри СУБД:
- Запись новой строки в таблицу
users(heap). - Дополнительно: Вставка новой записи (ключ:
'alice@example.com', значение: указатель на строку) в B-дерево индексаidx_users_email.
Вывод: Количество индексов на таблицу, подверженную частым изменениям (OLTP), должно быть тщательно сбалансировано. Каждый новый индекс улучшает чтение, но ухудшает запись.