Внутреннее объединение vs, где предложение подзапрос SQL Server

Я пытаюсь ускорить свою хранимую процедуру, поэтому я тестирую свою хранимую процедуру в двух форматах, используя статистику, как показано ниже

Способ 1: с помощью соединения

set statistics io on 

select top 2000   
    p.Vehicleno, 
    dbo.GetVehicleStatusIcon1(p.Direction, StatusCode, 0) as 'Status',
    location,
    Convert(varchar(13), p.TrackTime, 102) + ' ' + Convert(varchar(13), p.TrackTime, 108) AS 'TrackTime',
    p.Speed, p.Ignition
from 
    pollingdata p 
inner join 
    assignvehicletouser asn on asn.vehicleno = p.vehicleno
where 
    asn.empid = 1

Я получаю статистику как результат

Table 'Worktable'. Scan count 943, logical reads 7671, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'AssignVehicleToUser'. Scan count 1, logical reads 41, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'PollingData'. Scan count 1, logical reads 50, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

Способ 2: использование подзапроса предложения where

set statistics io on 

select top 2000 
    Vehicleno,
    dbo.GetVehicleStatusIcon1(Direction,StatusCode, 0) as 'Status',
    location,
    Convert(varchar(13), TrackTime, 102) + ' ' + Convert(varchar(13), TrackTime, 108) AS 'TrackTime',
    Speed, Ignition
from 
    pollingdata 
where 
    vehicleno in (select vehicleno 
                  from assignvehicletouser 
                  where empid = 1)

Я получаю статистику как результат

Table 'PollingData'. Scan count 1, logical reads 50, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'AssignVehicleToUser'. Scan count 1, logical reads 41, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

Нужно знать, какой из них лучше всего использовать?

Нужно объяснение о том, как логическое чтение работает здесь?

3 ответа

Если вам ничего не нужно от assignvehicletouser стол, я бы предпочел EXISTS (Это, вероятно, работает так же, как IN)

SELECT TOP (2000) p.Vehicleno
    , dbo.GetVehicleStatusIcon1(p.Direction, StatusCode, 0) AS 'Status'
    , location
    , CONVERT(VARCHAR(13), p.TrackTime, 102) + ' ' + CONVERT(VARCHAR(13), p.TrackTime, 108) AS 'TrackTime'
    , p.Speed
    , p.Ignition
FROM pollingdata p
WHERE EXISTS (
        SELECT 1
        FROM assignvehicletouser asn
        WHERE asn.vehicleno = p.vehicleno
            AND asn.empid = 1
        );

На основании предоставленных результатов статистики второй кажется лучше, так как первый имеет дополнительную операцию " рабочий стол" tempdb, которая используется для хранения временных / промежуточных операций / результатов, таких как операции SORTING

Логическое чтение: логическое чтение происходит каждый раз, когда страница читается из буферного кэша SQL-сервера, что хорошо.

Физическое чтение: происходит, когда требуемая страница данных недоступна в буферном кеше, система считывает ее с диска (физический ввод-вывод) и копирует в буферный кэш.

Вы можете использовать CROSS APPLY, чтобы присоединиться к UDF, вместо того, чтобы вызывать его напрямую, и в первом запросе условие WHERE (asn.emp=1) может напрямую применяться после условия 'ON', например asn.vehicleno = p.vehicleno AND asn.empid = 1

Обычно joins will work faster than inner queries, но в reality it will depend on the execution plan generated by SQL Server,

Независимо от того, как вы пишете свой запрос, SQL Server всегда будет преобразовывать его в план выполнения.

Если он достаточно "умен", чтобы сгенерировать один и тот же план из обоих запросов, вы получите тот же результат.

Вы можете прочитать Subquery или Join и здесь

Другие вопросы по тегам