пятница, 22 июля 2011 г.

MSSQL : Оптимизация запросов - убираем TOP 1

Иногда бывает необходимо получить только некие "верхние" записи из подчиненной таблицы
Кто-то делает так:
select *
, (select top 1 t2.id from t2 where t1Id = t1.id)
, (select top 1 t2.someData from t2 where t1Id = t1.id)
from t1


Чем плох такой вариант? А плох он следующим.
Мы ориентируемся на некое "верхнее" значение, которое может не относиться в нужной нам последовательности в итоге.
Кроме этого, у нас может возникнуть ситуация когда вызовы "верхнего" значения будут относиться к разным строкам таблицы.
Что тогда будете делать?
Поэтому я предлагаю использовать агрегирующий подзапрос

select *
from t1
inner join (select max(id) id, t1Id from t2 group by t1Id) T2i on t1.id = T2i.t1Id
inner join t2 on t2.id = T2i.id

В большинстве своем мы получим более лучший план запроса, эффективность во времени, предсказуемость (точность) результата.

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