Индексы — это одна из самых важных механизмов оптимизации производительности в реляционных базах данных. Они служат для ускорения операций поиска данных, подобно тому как оглавление книги помогает быстро найти нужную главу.
-- Без индекса: полное сканирование таблицы (Table Scan)
SELECT * FROM Customers WHERE LastName = 'Smith';
-- С индексом: быстрое точечное чтение (Index Seek)
CREATE INDEX IX_Customers_LastName ON Customers(LastName);
-- Без индекса: дорогая сортировка во временном пространстве
SELECT * FROM Products ORDER BY Price DESC;
-- С индексом: данные уже упорядочены
CREATE INDEX IX_Products_Price ON Products(Price);
-- Индекс для внешнего ключа значительно ускоряет JOIN
CREATE INDEX IX_Orders_CustomerID ON Orders(CustomerID);
SELECT c.Name, o.OrderDate
FROM Customers c
JOIN Orders o ON c.CustomerID = o.CustomerID;
-- Уникальный индекс предотвращает дублирование
CREATE UNIQUE INDEX UQ_Users_Email ON Users(Email);
-- Автоматически создает кластеризованный индекс
ALTER TABLE Employees ADD CONSTRAINT PK_Employees PRIMARY KEY (EmployeeID);
B-дерево структура:
Покрывающие индексы (Covering Indexes):
CREATE INDEX IX_Orders_Covering ON Orders(OrderDate) INCLUDE (TotalAmount, Status);
-- Запрос может быть выполнен только по индексу
SELECT OrderDate, TotalAmount FROM Orders WHERE Status = 'Shipped';
Операция | Без индекса | С индексом | Ускорение |
---|---|---|---|
Поиск 1 записи | 500ms | 5ms | 100x |
Сортировка 100K | 1200ms | 50ms | 24x |
JOIN двух таблиц | 3000ms | 150ms | 20x |
Замедление операций записи (INSERT/UPDATE/DELETE)
Дополнительное место на диске
Парадокс производительности:
SELECT * FROM sys.dm_exec_query_stats CROSS APPLY sys.dm_exec_sql_text(sql_handle);
SELECT * FROM sys.dm_db_missing_index_details;
SELECT * FROM sys.dm_db_index_usage_stats;
Индексы нужны для:
Грамотное проектирование индексов — это баланс между: