我知道从表中选择单行的两种不同方式(没有保证单条记录的where子句)。
SELECT TOP 1 [Id]
FROM [MyTable]
ORDER BY [Id] ASC
或
SELECT [Id]
FROM [MyTable]
ORDER BY [Id] ASC
OFFSET 0 ROWS
FETCH NEXT 1 ROWS ONLY
从统计意义上讲,其中哪些更快? ([Id]
是主键)
还是我不知道的这两种方法有更快的替代方法?
答案 0 :(得分:1)
计划之间没有区别。最高语法和按语法排序将使用相同的查询计划。但是,在某些情况下,可能会有一种更好的方法来查询此信息。
以下查询使用主键在表中伪造100,000行数据。然后使用前1种语法,offset fetch语法并最后使用where子句直接搜索来填充数据。
declare @t table
(
id int primary key clustered,
sometext nvarchar(150)
);
declare @runs int = 1;
while @runs<=100000
begin
insert @t (id, sometext)
values
(@runs, 'abc123');
select @runs=@runs+1;
end
SELECT TOP 1 [Id]
FROM @t
ORDER BY [Id] ASC;
SELECT [Id]
FROM @t
ORDER BY [Id] ASC
OFFSET 0 ROWS
FETCH NEXT 1 ROWS ONLY;
select id from @t where id=1;
该图像随后显示3个查询计划。前两个查询显示完全相同的计划,即使用主键进行的索引扫描。但是,第三个带有where子句的查询正在显示索引查找。这是因为如果您已经知道要查找的堆中的什么位置,则无需扫描整个数据集即可找到顶部。
索引查找的性能往往优于扫描,尤其是在具有许多不同数据类型列的大型表中。在这种非常简单的表结构和100,000行的情况下,当前批次中的成本完全相同(17%)。
对于更大的数据集,我建议采用一种类似以下的方法。
declare @id int = 0;
select @id=min(id) from @t;
然后,您可以在这样的where子句中使用此id变量。
select id, sometext from @t where id=@id;
哪个表可以使用索引查找计划,而该表的行数更多,并且比该测试更复杂。