Interview Question of the Week #044 – What is the difference of performance between SELECT and SET?

Question: What is the performance difference between SELECT and SET for variable assignment? SELECT can assign several variables in one statement; SET assigns one. That can reduce statement overhead in a tight loop, but choose the intended assignment behavior before choosing the apparent faster spelling.

Three separate watering cans stand beside three cans held in one carrier

The original experiment compared three SET statements with one SELECT assigning the same three values. It reported a faster loop with SELECT. That result illustrates the smaller statement count; it does not establish that SELECT is always the faster choice for every query or workload.

DECLARE @foo1 int, @foo2 int, @foo3 int;
SET @foo1=1; SET @foo2=2; SET @foo3=3;
SELECT @foo1 AS foo1,@foo2 AS foo2,@foo3 AS foo3;
SELECT @foo1=1,@foo2=2,@foo3=3;
SELECT @foo1 AS foo1,@foo2 AS foo2,@foo3 AS foo3;

DECLARE @Rows TABLE(Value int);
DECLARE @SetValue int=99,@SelectValue int=99,@ScalarSelect int=99;
SET @SetValue=(SELECT Value FROM @Rows);
SELECT @SelectValue=Value FROM @Rows;
SELECT @ScalarSelect=(SELECT Value FROM @Rows);
SELECT @SetValue AS SetNoRows,@SelectValue AS SelectNoRows,
       @ScalarSelect AS ScalarSelectNoRows;
INSERT @Rows VALUES(1),(2);
BEGIN TRY
 SET @SetValue=(SELECT Value FROM @Rows);
END TRY
BEGIN CATCH
 SELECT ERROR_NUMBER() AS MultipleRowError;
END CATCH;
Native SQL Server 2025 results from the copyable example: NULL, 99, NULL for zero rows, followed by the expected scalar-subquery error 512.
Native SQL Server 2025 results from the copyable example: NULL, 99, NULL for zero rows, followed by the expected scalar-subquery error 512.

The differences that cause real bugs

Both first result grids contain 1, 2, 3. The empty-table test then returns NULL, 99, NULL. SELECT assigning from rows leaves its variable unchanged when no rows qualify. SELECT assigning a scalar subquery sets NULL when that subquery is empty, just like SET.

The two-row scalar SET reports error 512. A direct SELECT assignment from several rows instead keeps one returned value, with no useful ordering guarantee unless the query is deliberately constrained. It should not hide a violation of the application’s one-value expectation.

SET is the standard variable-assignment form and Microsoft’s recommended default. Use a multi-variable SELECT when its single-row semantics are deliberate and clear. Resetting a variable before a direct SELECT can avoid stale values, but it does not fix an unexpectedly multirow source.

Do not rely on the order of assignments within one SELECT to make one variable depend on another newly assigned variable. This question is about statement overhead and semantics, not a reason to introduce loops into a set-based task.

Published by Pinal Dave on SQLAuthority. More of my work at pinaldave.com.


Discover more from SQL Authority with Pinal Dave

Subscribe to get the latest posts sent to your email.

SQL Scripts
Previous Post
Interview Question of the Week #043 – What is the Difference Between EXCEPT operator vs. NOT IN
Next Post
Interview Question of the Week #045 – How to Do Case Sensitive Search?

Related Posts

3 Comments. Leave new

  • ANSI versus Microsoft dialect is messier than just this. In ANSI, the construction is always “SELECT .. FROM..” ; there is never a SELECT without a FROM clause. The SET operator can use a row constructor to do what T-SQL proprietary syntax does.
    SET (a,b,c) = (x,y,z);

    But it can also do more complex assignments.

    Reply
  • When using the row constructor, does it still execute each individually (making it still slower than SELECT)?

    Reply
  • I would say that it is better to use SET if you want to assign a value to a variable. Some more examples at

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

Fill out this field
Fill out this field
Please enter a valid email address.