【问题标题】:What is the fastest way to select a single row in SQL? (SQL Server)在 SQL 中选择单行的最快方法是什么? (SQL 服务器)
【发布时间】:2019-09-24 06:10:37
【问题描述】:

我知道从表中选择单行的两种不同方法(没有保证单条记录的 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] 是主键)

或者有没有我不知道的更快的替代方案?

【问题讨论】:

  • 它们应该有相同的执行计划和相同的性能。
  • 两者都试一下,看看执行计划。
  • Or is there a faster alternative... SELECT MAX([Id]) AS [Id] FROM [MyTable]。如果执行计划更快,则必须比较执行计划,这取决于您的索引结构。另见MAX vs Top 1 - which is better?
  • 您可以在 SELECT 之前使用 SET STATISTICS PROFILE 关键字检查更快的方式,这样会尝试请求并返回您的统计信息请求:)
  • 由于某种原因,我对执行计划的理解异常糟糕。 @KiloumapMrz 我会试试的,谢谢!

标签: sql sql-server performance query-performance sqlperformance


【解决方案1】:

计划之间没有区别。顶级语法和按语法排序将使用相同的查询计划。但是,在某些情况下,查询此信息可能有更好的方法。

下面的查询伪造了一个表中的 100,000 行数据,并带有一个要搜索的主键。然后执行填充数据,使用 top 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 个查询计划。前 2 个查询显示完全相同的计划,即使用主键的索引扫描。但是,带有 where 子句的第三个查询显示了索引查找。这是因为如果您已经知道要在堆中查找的位置,则无需扫描整个数据集即可找到顶部。

索引查找往往比扫描执行得更好,尤其是在具有大量不同数据类型的列的大型表中。在这个非常简单的表结构和 100,000 行的场景中,成本在当前批次中完全相同(17%)。

对于更大的数据集,我主张采用类似这样的方法。

declare @id int = 0;
select @id=min(id) from @t;

然后你可以像这样在 where 子句中使用这个 id 变量。

select id, sometext from @t where id=@id;

这可以在具有更多行/比此测试更复杂的表中利用索引查找计划。

【讨论】:

  • 是的,我正在使用一个包含数百万条记录和超过 2 列的表。我会测试你的建议,看看它有什么不同。
  • 这比我以前做的要快。不能举出例子,因为查询的其余部分很糟糕,但你肯定帮助加快了速度。谢谢!将其标记为答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-03-16
  • 1970-01-01
  • 1970-01-01
  • 2011-01-23
  • 1970-01-01
  • 2020-01-09
  • 2016-08-17
相关资源
最近更新 更多