- Прежде всего, когда вы работаете над 100 миллионами + записей, и это
слишком объединяясь с другими таблицами, первое, что я хотел бы спросить, является то, что является
обоснование не создания индексов, которые могут покрыть ваш запрос. Если
Вы не администратор этой системы, я бы предложил вам
следует довести это до группы администраторов и попытаться понять, что
точная причина (если таковая имеется) они не хотят индексировать эту огромную таблицу.
Тем более, что вы упомянули " эффективность очень важна для
меня ».
Помните, что «Настройка SQL» - это только один из этапов «Настройка производительности базы данных», и вы можете настроить только столько, сколько сможете написать хороший SQL-запрос. Когда объем данных становится огромным, хорошего SQL-запроса никогда не бывает достаточно без принятия других мер по настройке производительности.
- Помимо того, что уже предоставил Роджер, вот несколько решений, которые вы можете попробовать:
Раствор 1
SELECT T1.ID_1, OA.ID_2, OA.Location
FROM Table1 T1
OUTER APPLY (
SELECT TOP 1 T3.ID_2, T3.Location
FROM Table2 T2
INNER JOIN Table3 T3
ON T2.ID_2 = T3.ID_2
WHERE T2.ID_1 = T1.ID_1
ORDER BY T3.Date DESC
) OA;
Решение 2:
SELECT DISTINCT
T1.ID_1
,T2.ID_2
,Location = FIRST_VALUE(T3.Location) OVER (PARTITION BY T1.ID_1 ORDER BY T3.Date DESC)
FROM Table1 T1
INNER JOIN Table2 T2
ON T1.ID_1 = T2.ID_1
INNER JOIN Table3 T3
ON T2.ID_2 = T3.ID_2;
Подготовка данных:
DROP TABLE IF EXISTS Table1
DROP TABLE IF EXISTS Table2
DROP TABLE IF EXISTS Table3
SELECT TOP 10000 ID_1 = object_id, name
INTO Table1
FROM sys.all_objects
ORDER BY object_id
SELECT ID_1 = T1.ID_1, ID_2 = IDENTITY(INT, 1, 1)
INTO Table2
FROM Table1 T1
CROSS JOIN Table1 T2
SELECT ID_2, Location = 'City_'+ CAST(ID_2 AS VARCHAR(100)), Date = CAST(DATEADD(DAY, ID_2/10000, GETDATE()) AS DATE)
INTO Table3
FROM Table2
Указатели для решения 1:
CREATE NONCLUSTERED INDEX IX_TABLE1_ID_1 ON Table1 (ID_1)
CREATE NONCLUSTERED INDEX IX_TABLE2_ID_2 ON Table2 (ID_1, ID_2)
CREATE NONCLUSTERED INDEX IX_TABLE3_ID_2 ON Table3 (ID_2, Date DESC) INCLUDE (Location)
План выполнения:
Вы можете видеть, что все они - «Поиск по индексу», кроме Таблицы 1, которая является законным «Сканированием по индексу», поскольку вы выполняете сканирование для каждого значения значения ID_1 в Таблице1. Если вы поместите предложение where во внешний цикл для поиска нескольких конкретных значений ID_1, то это «сканирование индекса» также превратится в «поиск индекса».
Я оставлю Индексную стратегию для 2-го решения вам (в качестве домашней работы :)). Советы: Вы должны сделать местоположение как ключ, а также. Или вы можете использовать индексный подход COLUMNSTORE.