1

我正在尝试加快我的存储过程,所以我使用如下统计 io 以两种格式测试我的存储过程

方法一:使用join

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.

方法二:使用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.

需要知道哪个最好用?

需要解释一下这里的逻辑读取是如何工作的吗?

4

3 回答 3

7

如果您不需要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
        );
于 2015-01-30T10:47:28.593 回答
1

根据提供的统计结果,第二个似乎更好,因为第一个具有额外的 tempdb“工作表”操作,用于保存临时/中间操作/结果,如 SORTING 操作

逻辑读取每次从 SQL 服务器缓冲区缓存读取页面时都会发生逻辑读取,这很好。

物理读取:当所需的数据页在缓冲区缓存中不可用时发生,系统从磁盘(物理IO)读取它并复制到缓冲区缓存。

您可以使用 CROSS APPLY 来加入 UDF 而不是直接调用它,并且在第一个查询中 WHERE 条件 (asn.emp=1) 可以在 asn.vehicleno = p.vehicleno AND asn.empid = 1 等“ON”条件之后直接应用

于 2015-01-30T12:11:02.247 回答
0

通常joins will work faster than inner queries,但在reality it will depend on the execution plan generated by SQL Server.

无论您如何编写查询,SQL Server 都会在执行计划上对其进行转换。

如果它足够“聪明”,可以从两个查询中生成相同的计划,那么您将得到相同的结果。

您可以在此处阅读子查询或加入

于 2015-01-30T10:33:11.243 回答