Blog Post

You don’t really need ORDER BY do you?

,

You see dozens of blog posts and articles about how the order of a result set is not guaranteed without an ORDER BY clause and here is my contribution to the subject.

You all know I love examples so without further ado here we go:

Using data from AdventureWorks2014

-- Create and load the test table
SELECT AddressId, AddressLine1, AddressLine2, City, 
StateProvinceCode, PostalCode, SpatialLocation, 
Addr.rowguid, Addr.ModifiedDate
INTO OrderByTest
FROM Person.Address Addr
JOIN Person.StateProvince StateP
ON Addr.StateProvinceID = StateP.StateProvinceID;
-- Create a clustered PK and a non-clustered index
ALTER TABLE OrderByTest ADD CONSTRAINT pk_OrderByTest 
PRIMARY KEY (AddressId);
CREATE INDEX nci_OrderByTest_State_Zip 
ON OrderByTest(StateProvinceCode, PostalCode);
GO

Now that we have some data we run a report query.

-- "Report" query
SELECT * FROM OrderByTest WHERE StateProvinceCode = 'TX';

OrderByTest1

This is great, our information is ordered by PostalCode. Exactly the way we wanted it. No need to put an ORDER BY clause in the query right? You can run it 100 times and it’s still going to give you the information in PostalCode order. (Well probably, remember that without ORDER BY the order is not actually guaranteed.)

Over the next few months we get an influx of customers from Texas.

-- Adding additional rows for Texas the easy way
-- The @Count piece keeps AddressID unique.
DECLARE @Count INT;
SELECT @Count = MAX(AddressID) FROM OrderByTest;
INSERT INTO OrderByTest
SELECT AddressId + @Count, AddressLine1, AddressLine2, City, 
'TX' StateProvinceCode, PostalCode, SpatialLocation, 
Addr.rowguid, Addr.ModifiedDate
FROM Person.Address Addr;

It’s time to run the report again.

-- "Report" query
SELECT * FROM OrderByTest WHERE StateProvinceCode = 'TX';

OrderByTest3

Hu? What happened, now instead of being ordered by PostalCode the data is ordered by AddressId.

Looking at the execution plans will help.

Execution Plan from the first run.

OrderByTest2

Execution Plan from the second run.

OrderByTest4

You can see that the execution plan changes. Initially there were not that many addresses (percentage wise) in Texas so SQL decided to use an index seek on the State/PostalCode index with a key lookup to get the additional data. Once there was a high percentage of addresses in Texas SQL decided it would be faster to just us a clustered index scan. Because of the change in plan the order of the output changed.

-- Clean up code
DROP TABLE OrderByTest;

Now this is just a demonstration of one possible way the order of the data could unexpectedly change. Hopefully it brings home just how important that ORDER BY clause is. Even if the execution plan were to stay the same there is no guarantee that the data order will remain the same without an ORDER BY clause.

Filed under: Microsoft SQL Server, SQLServerPedia Syndication, T-SQL Tagged: code language, language sql, microsoft sql server, order by, sql statements, T-SQL

Rate

You rated this post out of 5. Change rating

Share

Share

Rate

You rated this post out of 5. Change rating