views:

1270

answers:

3

I've been led to believe that for single variable assignment in T-SQL, set is the best way to go about things, for two reasons:

  • it's the ANSI standard for variable assignment
  • it's actually faster than doing a SELECT (for a single variable)

So...

SELECT @thingy = 'turnip shaped'

becomes

SET @thingy  = 'turnip shaped'

But how fast, is fast? Am I ever really going to notice the difference?

A: 

Take a look at the "execution plan", it should tell you the cost of each line of your statement

Mark
if you look at the execution plan for both of these, you'll see they both have a cost of zero
ninesided
well thats basically your answer, the cost is negligible, so just stick with SET would be my advice
Mark
+1  A: 

I don't speed is an issue, it has to do with more with the assignment feature set. I came across this a while ago and there is something new in SQL Server 2008...I heard, try googling SQL Set vs Select SQL SERVER 2008

Saif Khan
Would the voter that gave me -1 be man enough to say why?????
Saif Khan
I think that's why we are here...to get answers.
Saif Khan
How would you answer this then http://stackoverflow.com/questions/189610/speed-of-mulitple-variable-assignment-in-t-sql
Saif Khan
I suspect you're kind of right, I think it might be down to one using less CPU time than the other but I'm not sure how to verify this
ninesided
+5  A: 

SET is faster on single runs. You can prove this easily enough. Whether or not it makes a difference is up to you, but I prefer SET, since I don't see the point of SELECT if all the code is doing is an assignment. I prefer to keep SELECT confined to SELECT statements from tables, views, etc.

Here is a sample script, with the number of runs set to 1:

SET NOCOUNT ON

DECLARE @runs int
DECLARE @i int, @j int
SET @runs = 1
SET @i = 0
SET @j = 0

DECLARE @dtStartDate datetime, @dtEndDate datetime


WHILE @runs > 0
    BEGIN
     SET @j = 0
     SET @dtStartDate = CURRENT_TIMESTAMP
     WHILE @j < 1000000
      BEGIN
       SET @i = @j
       SET @j = @j + 1
      END
     SELECT @dtEndDate = CURRENT_TIMESTAMP
     SELECT DATEDIFF(millisecond, @dtStartDate, @dtEndDate) AS SET_MILLISECONDS


     SET @j = 0
     SET @dtStartDate = CURRENT_TIMESTAMP
     WHILE @j < 1000000
      BEGIN
       SELECT @i = @j
       SET @j = @j + 1
      END
     SELECT @dtEndDate = CURRENT_TIMESTAMP
     SELECT DATEDIFF(millisecond, @dtStartDate, @dtEndDate) AS SELECT_MILLISECONDS

     SET @runs = @runs - 1
    END

RESULTS:

Run #1:

SET_MILLISECONDS

5093

SELECT_MILLISECONDS

5186

Run #2:

SET_MILLISECONDS

4876

SELECT_MILLISECONDS

5466

Run #3:

SET_MILLISECONDS

4936

SELECT_MILLISECONDS

5453

Run #4:

SET_MILLISECONDS

4920

SELECT_MILLISECONDS

5250

Run #5:

SET_MILLISECONDS

4860

SELECT_MILLISECONDS

5093

Oddly, if you crank the number of runs up to say, 10, the SET begins to lag behind.

Here is a 10-run result:

SET_MILLISECONDS

5140

SELECT_MILLISECONDS

5266

SET_MILLISECONDS

5250

SELECT_MILLISECONDS

5466

SET_MILLISECONDS

5220

SELECT_MILLISECONDS

5280

SET_MILLISECONDS

5376

SELECT_MILLISECONDS

5280

SET_MILLISECONDS

5233

SELECT_MILLISECONDS

5453

SET_MILLISECONDS

5343

SELECT_MILLISECONDS

5423

SET_MILLISECONDS

5360

SELECT_MILLISECONDS

5156

SET_MILLISECONDS

5686

SELECT_MILLISECONDS

5233

SET_MILLISECONDS

5436

SELECT_MILLISECONDS

5500

SET_MILLISECONDS

5610

SELECT_MILLISECONDS

5266

Pittsburgh DBA
nice, this is the kind of hard evidence I was looking for! Thanks dude!
ninesided
This is good to know.
Saif Khan