Внутреннее объединение 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 и здесь