What is the fastest way to select a single row in SQL? (SQL Server)

18,363

There is no difference between the plans. The top syntax and order by syntax will utilise the same query plan. However for certain circumstances there may be a slightly better way to query out this information.

Below query fakes 100,000 rows of data in a table with a primary key to search on. Then executes populating the data, using the top 1 syntax, the offset fetch syntax and finally the direct search with a where clause.

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;

Query Plans

The image then shows the 3 query plans. The first 2 queries show the exact same plan, an index scan using the primary key. However the third query with the where clause is showing an index seek. This is because the whole data set does not need to be scanned to find the top if you already know where in the heap you are looking.

Index seeks tend to perform better than scans, particularly in large tables with a lot of columns of different data types. In this scenario with a very simple table structure and 100,000 rows, the cost is exactly the same in the current batch (17%).

For a larger data set I'd argue for an approach which looks something like this.

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

Then you can use this id variable in a where clause like this.

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

Which can take advantage of the index seek plan in a table which has more rows/is more complicated that this test.

Share:
18,363

Related videos on Youtube

Werns
Author by

Werns

Updated on May 25, 2022

Comments

  • Werns
    Werns about 2 years

    I know of two different ways to select a single row from a table (without a where clause that guarantees a single record).

    SELECT TOP 1 [Id]
    FROM [MyTable]
    ORDER BY [Id] ASC
    

    or

    SELECT [Id]
    FROM [MyTable]
    ORDER BY [Id] ASC
    OFFSET 0 ROWS
    FETCH NEXT 1 ROWS ONLY
    

    Which of these is statistically faster? ([Id] is a primary key)

    Or is there a faster alternative to both of these that I'm unaware of?

    • Gordon Linoff
      Gordon Linoff about 5 years
      They should have the same execution plan and the same performance.
    • Sean Lange
      Sean Lange about 5 years
      Try both and look at the execution plans.
    • Igor
      Igor about 5 years
      Or is there a faster alternative... <= You could use an aggregate: SELECT MAX([Id]) AS [Id] FROM [MyTable]. You would have to compare the execution plans if it is faster, depends on your index structure. See also MAX vs Top 1 - which is better?
    • Kiloumap Mrz
      Kiloumap Mrz about 5 years
      You can check the faster way with SET STATISTICS PROFILE key word before your SELECT This way will try the request and return you the stats of your request :)
    • Werns
      Werns about 5 years
      For some reason I'm exceptionally bad at understanding the execution plans. @KiloumapMrz I'll try that out, thanks!
    • David Browne - Microsoft
      David Browne - Microsoft about 5 years
      You only need to understand plans to answer why one query is more expensive. SET STATISTICS PROFILE is sufficient to tell you which query is more expensive.
  • Werns
    Werns about 5 years
    Yeah I'm using a table with millions of records and more than 2 columns. I'll test out your suggestion and see what kind of difference it makes.
  • Werns
    Werns about 5 years
    This is faster than what I was doing before. Can't give examples because the rest of the query sucks but you've definitely helped speed it up. Thanks! Marked it as the answer.