27.3.26

Перегружена ли индексами ваша база данных?

Автор: Luca Biondi, Is Your Database Over-Indexed? Your Indexes Might Be Killing Performance

👉 Если вы пропустили мою предыдущую статью, ознакомьтесь с ней здесь: Прекратите дефрагментировать индексы! Доступна для предварительного изучения функция Auto Index Compaction

Ваш запрос работает медленно.
И вы добавляете индекс.

Запрос ускоряется… на мгновение.

Но затем всё остальное начинает работать медленнее.

👉 Что же произошло?

Возможно, вы перегружаете свою базу данных индексами.

🧠 Миф: «Чем больше индексов, тем выше производительность»

Индексы — это мощный инструмент.
Но они не бесплатны.

Они ускоряют запросы SELECT
Они замедляют операции INSERT / UPDATE / DELETE
Они потребляют память и место на диске
Они увеличивают нагрузку на процессор
💣 Индексы не просто ускоряют запросы… они замедляют всё остальное.

🔥 Реальный пример – взрывная переиндексация

CREATE INDEX IX_Orders_Date ON Orders(OrderDate);
CREATE INDEX IX_Orders_Customer ON Orders(CustomerId);
CREATE INDEX IX_Orders_Status ON Orders(Status);
CREATE INDEX IX_Orders_Date_Status ON Orders(OrderDate, Status);
CREATE INDEX IX_Orders_Customer_Status ON Orders(CustomerId, Status);

❌ Проблема:

  • Пересекающиеся индексы
  • Избыточные структуры данных
  • Потраченное впустую место на диске
  • Более высокие затраты на обслуживание

💣 У вас не 5 индексов… у вас 5 проблем.

🔥 Скрытая цена – плата за запись (WRITE Penalty)

INSERT INTO Orders (...)
VALUES (...)

Каждый раз, когда вы вставляете строку:

  • Все индексы должны быть обновлены
  • Журнал транзакций растёт
  • Увеличивается количество locks и latches

💣 Каждая операция вставки умножается на количество индексов.

🔥 Пример – неиспользуемые индексы (молчаливый убийца)

SELECT *
FROM sys.dm_db_index_usage_stats
WHERE database_id = DB_ID()
AND user_seeks = 0
AND user_scans = 0;

👉 Это индексы, которые:

  • Никогда не используются
  • Но всё равно потребляют ресурсы

💣 Самый опасный индекс — тот, который никто не использует.

🔥 Пример – дублирующиеся индексы

SELECT 
    i1.name,
    i2.name
FROM sys.indexes i1
JOIN sys.indexes i2 
ON i1.object_id = i2.object_id
AND i1.index_id <> i2.index_id;

👉 Во многих базах данных существуют индексы, выполняющие ОДНУ И ТУ ЖЕ работу.

🧪 Бенчмарк №1 – стоимость операции INSERT

СценарийВремя вставкиЦППримечания
2 индекса120 мсНизкаяБыстрая запись
8 индексов850 мсВысокаяЗначительные накладные расходы

👉 Те же самые данные… но больше индексов → замедление вставок в 7 раз.

🧪 Бенчмарк №2 – выигрыш SELECT против затрат

ИндексыВремя запросаВыигрыш
1 индекс300 мсБазовый уровень
3 индекса120 мсХорошо
8 индексов110 мсМинимальный прирост

💣 Убывающая отдача: больше индексов ≠ выше производительность.

📊 Всегда помните:

👉 Больше индексов = экспоненциальный рост затрат на запись. Будьте осторожны!

🚀 Как это исправить (мои 4 золотых правила):

  • Удалите неиспользуемые индексы
  • Объедините дублирующиеся индексы
  • Используйте INCLUDE вместо дублирования ключевых столбцов
  • Регулярно отслеживайте информацию в DMV

💣 Последняя мысль
Самая быстрая база данных — это не та, у которой больше индексов… а та, у которой они правильные.

👉 Больше индексов ≠ больше скорости.
👉 Больше индексов = больше затрат.

👉 Моё кредо: Оптимизируйте с умом. А не просто «больше».




Комментариев нет:

Отправить комментарий