There is this myth among developers and DBAs that SQL Server has a natural order that is logical and predictable (and can therefore be relied on). Not so! I wanted to take a few moment to explain and debunk the myth, explain how VistaDB is different, and share something I learned along the way.
The Myth(s)
- SQL Server stores entries in a natural order based upon the first column.
- SQL Server always appends inserted rows at the end of the current table.
- Unindexed data is always available in the order it was inserted.
Have you heard those as well? In most databases an insert is always appended to the end of the current table, this is for ease of insertion and for multi threading where you want to lazy write to the database after the insert (of course servers can get away with that, but we can’t because we don’t know when your application will go away and kill us).
You can’t actually count on ANY of those from SQL Server.
Select * always returns the same order
Many times developers pull a SELECT * from the database in SQL Server and think the order will not change – IT CAN CHANGE. If you do not explicitly put an order by clause on your select you have no guarantee of ordering in SQL Server.
EDIT
You can read the full explanation why this happens over at the SQL Serverpedia blog entry on natural order. I am not sure if this was the original or a repost from Brad's blog, but I wanted to give credit to where I originally read it. The article at SQL Serverpedia was emailed to me from a user asking about how VistaDB works in this same situation. I then got the same article from 2 other users in the same week... Sounded like a good time to do a blog about it.
As was pointed out in the comments below, the original article came from another blog. Brad Schulz did the original article on this topic and you can read his blog for the complete details. Trust me if you love SQL technology you will love that article. It is very well laid out and explains everything in depth that only a true SQL geek can love (like me!).
Take a look at this SQL:
create table ordertest
(
col1 varchar(900) not null
,col2 char(1) not null
);
-- STEP 1 insert some data
insert ordertest values ('B'+replicate('.',899),'N');
insert ordertest values ('R'+replicate('.',899),'A');
insert ordertest values ('A'+replicate('.',899),'T');
insert ordertest values ('D'+replicate('.',899),'U');
insert ordertest values ('S'+replicate('.',899),'R');
insert ordertest values ('C'+replicate('.',899),'A');
insert ordertest values ('H'+replicate('.',899),'L');
insert ordertest values ('U'+replicate('.',899),'O');
insert ordertest values ('L'+replicate('.',899),'R');
insert ordertest values ('Z'+replicate('.',899),'D');
select * from ordertest;
-- STEP 2 insert two more values
insert ordertest values ('X','X');
insert ordertest values ('Y','Y');
select * from ordertest;
What do you think the first and second select statements look like? The first is probably what you expected, the second probably is not!
More...