2016-09-11 4 views
3

Я пытался оптимизировать следующий запрос. Два подзапроса, которые используются, могут сделать его одним запросом.Как оптимизировать следующий запрос

select fn.id, 
(select top 1 s.rid from find f join status s on f.fid = s.fid 
        where f.fid = fn.id and f.active = 1) as rid, 
(select top 1 f.gid from find f 
        where f.fid = fn.id and f.active = 1) as gid 
      from finding fn where f.tid = 'abcd' 

Я использовал КВО для присоединиться к подзапрос, поскольку он запускается на выполнение снова и снова для каждой итерации, но я хочу спросить некоторых экспертов DBA здесь, что может быть возможным и оптимальным решением для следующего запроса будет оптимизирован. Любая помощь приветствуется.

ответ

2

Использование OUTER APPLY

SELECT fn.id, 
     oa.rid, 
     oa.gid 
FROM finding fn 
     OUTER apply (SELECT TOP 1 s.rid, 
           f.gid 
        FROM find f 
          JOIN status s 
          ON f.fid = s.fid 
        WHERE f.fid = fn.id 
          AND f.active = 1) oa 
WHERE f.tid = 'abcd' 

Примечание: Вы используете TOP 1 с вне Order by вы получите произвольные записи в результате.

0

Это должно работать лучше:

select fn.id, t.rid, t.gid 
from finding fn 
join (
    select f.fid, s.rid, f.gid, 
      row_number() over (order by select null) as rn 
    from find f 
    join status s on f.fid = s.fid 
    where f.active = 1 
) as t on t.fid = fn.id and rn = 1 
where fn.tid = 'abcd' 

TOP 1 в исходном запросе выполняется без ORDER BY пункта, так что не ясно, какая запись должна быть выбрана. Вы можете заменить select null в вышеприведенном запросе на поле, определяющее выбор верхней строки.

+0

В случае, если OP имеет индекс в столбце «ID», все же я думаю, что он будет сканировать все записи для каждого 'ID' для генерации' Row_number' –

Смежные вопросы