SQL Server: Order of Rows

SQL Server: Order of Rows

問題

We all know that a simple statement such as:

SELECT * FROM stuff;
should not produce an ordered result. However, when I try to demonstrate this, it always comes out in primary key order.

Moreover a statement such as:

SELECT thing,whatever FROM stuff
GROUP BY thing,whatever;
always appears to sort thing by the last field in the GROUP BY clause, which is not at all helpful.

The question is, under what circumstances does SQL SERVER order the result even if unasked, and what can I do to stop this?

I am trying to demonstrate to my students that order is indeterminate unless specified, but this is not helping my case.

I admit that I am working with a small set of sample data.

Thanks

 

回答1

under what circumstances does SQL SERVER order the result even if unasked?

This might happen if the access path to retrieve the data happens to produce data already ordered e.g. an index scan in key order. Or if the plan contains an explicit sort in order to provide data in order for operators that require this, such as merge join or stream aggregate. Without an explicit order by no order is guaranteed but SQL Server won't go out of its way to prevent results being output in order either.

and what can I do to stop this?

For the first query you can see different ordering if SQL Server uses an allocation order scan.

So make sure the table is at least 64 pages in size and that the allocation order isn't the same as key order then run the query at read uncommitted isolation level.

CREATE TABLE T
(
X INT IDENTITY PRIMARY KEY,
Y CHAR(4000)
);

INSERT INTO T
SELECT TOP 100 'A'
FROM master..spt_values;

/* Cause page splits so key order and allocation order differ
   and leaves one row per page so table is now > 64 pages*/
ALTER TABLE T ALTER COLUMN Y CHAR(4001);

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;

SELECT *
FROM T;
The read uncommitted isn't required for the above in the case that a table lock is taken, there is a hint for that but a less obvious way would be to change the above table definition to

CREATE TABLE T
(
X INT IDENTITY PRIMARY KEY WITH(allow_row_locks = off, allow_page_locks = off),
Y CHAR(4000)
);
And then hopefully you will see disordered results without having to change the isolation level.

For the second query you want a hash aggregate rather than a stream aggregate. You can force this with a query hint or less obviously with a plan guide but this is more likely to be chosen organically if there are relatively few distinct groups compared to the size of the table.

 

回答2

This article by Conor Cunningham (Software Architect, SQL Server Engine at Microsoft) should answer your questions:

No Seatbelt – Expecting Order without ORDER BY
Some extracts below:

The hard part here is that there is no reasonable way for any external user to know when a plan will change . The space of all plans is huge and hurts your head to ponder. SQL Server's optimizer will change plans, even for simple queries, if enough of the parameters change. You may get lucky and not have a plan change, or you can just not think about this problem and add an ORDER BY.

[...]

There are lots of situations where plans can change in the Optimizer - for more complex queries, there can be thousands of plan choices or more, and each of them has a case when it would likely be picked. For each of those plans, the sort for that plan can be different if you don't specify it.

So, my advice for the day:

If you need order in your query results, put in an ORDER BY. It's that simple. Anything else is like riding in a car without a seatbelt.

 

What is the default order of records for a SELECT statement in MySQL?

問題

Suppose you have the following table and data:

create table t (
    k int,
    v int,
    index k(k)
    ) engine=memory;

insert into t (k, v)
values (10, 1),
       (10, 2),
       (10, 3);
When issuing select * from t where k = 10 with no order by clause, how does MySQL sort the records by default?

 

回答1

Reposting my answer to a similar question regarding SQL Server:

In the SQL world, order is not an inherent property of a set of data. Thus, you get no guarantees from your RDBMS that your data will come back in a certain order -- or even in a consistent order -- unless you query your data with an ORDER BY clause.

So, to answer your question:

MySQL sorts the records however it wants without any guarantee of consistency.
If you intend to rely on this order for anything, you must specify your desired order using ORDER BY. To do anything else is to set yourself up for unwelcome surprises.
This is a property of all SQL, not just MySQL. The relevant text in the SQL-92 spec is:

If an <order by clause> is not specified, then the ordering of the rows of Q is implementation-dependent.

There are similar bits of text in the spec for cursors.

 

回答2

The order of the rows in the absence of ORDER BY clause may be:

different between any two storage engines;
if you use the same storage engine, it might be different between any two versions of the same storage engine; Example here, scroll down to "Ordering of Rows".
if the storage engine version is the same, but MySQL version is different, it might be different because of the query optimizer changes between those versions;
if everything is the same, it could be different due to the moon phase and that is OK.

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章