Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

insert into tbl1 select * from tbl2order by field1 doesnt work!

159 views
Skip to first unread message

cooltech77

unread,
May 23, 2006, 1:15:33 PM5/23/06
to
Hi

I am trying to insert records from tbl2 into tbl1 in a sorted order but its
not working.

insert into tbl1 select * from tbl2order by field1

The records are not being added in a sorted order.can anyone please explain?

Thanks for your help

Stu

unread,
May 23, 2006, 1:37:11 PM5/23/06
to
I hate to borrow a line from Celko, but you need to go back and review
your knowledge of an RDBMS; tables are unordered by definition.

Sorry,
Stu

Mark Williams

unread,
May 23, 2006, 1:38:02 PM5/23/06
to
Rows in tables have no natural order, so you cannot specify in what order
rows are inserted into a table. It should not matter to you in which order
they are inserted anyway, because you can control in what order they are
displayed with the ORDER BY clause of SELECT.

When you open a table in Enterprise Manager, or use a SELECT statement
without an ORDER BY clause, the table is sorted by its primary key.

--

Jim Underwood

unread,
May 23, 2006, 1:39:48 PM5/23/06
to
Inserts will never happen in any particular order. SQL simply does not work
that way. Data is never ordered in tables, although you can order it when
you are selecting it from a table. Even then, the order only applies to the
end result that is returned to the user, or as needed by certain functions.

If you want it ordered, you have to order it when you select from the
table. If you need certain ordered IDs assigned to each value you can use a
couple of tricks to accomplish it. Do a search in this forum on "Rank" and
you will find some options.

"cooltech77" <coolt...@discussions.microsoft.com> wrote in message
news:C65BEC14-BE54-444A...@microsoft.com...

Alejandro Mesa

unread,
May 23, 2006, 1:41:03 PM5/23/06
to
cooltech77,

> The records are not being added in a sorted order.can anyone please explain?

How do you know it?


AMB

NumbLock

unread,
May 23, 2006, 2:00:58 PM5/23/06
to
If you want to enforce a certain order of the table without having to
use the order by clause, use a clustered index (assuming the column is a
good candidate for an index)

Tibor Karaszi

unread,
May 23, 2006, 2:00:37 PM5/23/06
to
> When you open a table in Enterprise Manager, or use a SELECT statement
> without an ORDER BY clause, the table is sorted by its primary key.

No, SQL Server doesn't impose such an overhead. The order of the rows in these cases (when you don't
have ORDER BY) is solely dependent on the execution plan you happen to get for that particular
execution.

--
Tibor Karaszi, SQL Server MVP
http://www.karaszi.com/sqlserver/default.asp
http://www.solidqualitylearning.com/


"Mark Williams" <MarkWi...@discussions.microsoft.com> wrote in message
news:6A82BA94-8F21-4FCF...@microsoft.com...

Vern Rabe

unread,
May 23, 2006, 2:05:02 PM5/23/06
to

"Mark Williams" wrote:
> When you open a table in Enterprise Manager, or use a SELECT statement
> without an ORDER BY clause, the table is sorted by its primary key.

Mark:

Not necessarily true. From BOL, "the rows in a result set cannot be assumed
to have any sequence unless ORDER BY is specified".

Vern

Jim Underwood

unread,
May 23, 2006, 2:07:00 PM5/23/06
to
In this case the index chosen for the execution plan will often determine
the order of the results, correct? Which means if SQL Server happens to use
the PK index in the execution plan, then the result will (coincidently, but
not by design) be returned in PK order? Meaning that the perception that
SQL Server will order by PK is simply a side effect of it using the PK index
in that particular situation?

"Tibor Karaszi" <tibor_please.n...@hotmail.nomail.com> wrote in
message news:%23IZBNLp...@TK2MSFTNGP03.phx.gbl...

Jim Underwood

unread,
May 23, 2006, 2:08:45 PM5/23/06
to
Just going by what others have said about this, isn't this behavior
dependent on SQL Server using the clustered index on that particular
execution plan? If, for any reason, the clustered index is not used, the
order will still be random, no?

"NumbLock" <pcg...@yahoo.com> wrote in message
news:%235VtwJp...@TK2MSFTNGP05.phx.gbl...

Tibor Karaszi

unread,
May 23, 2006, 2:15:36 PM5/23/06
to
> In this case the index chosen for the execution plan will often determine
> the order of the results, correct?

Almost. Replace the word "often" with "always". :-)


> Which means if SQL Server happens to use
> the PK index in the execution plan, then the result will (coincidently, but
> not by design) be returned in PK order?

Most probably, but it depends on *how* it uses the PK. It can for instance do a lookup using the IAM
page (methinks) and the rows will more resemble the physical order in the database file.

> Meaning that the perception that
> SQL Server will order by PK is simply a side effect of it using the PK index
> in that particular situation?

Exactly. :-)


"Jim Underwood" <james.underwoodATfallonclinic.com> wrote in message
news:uDy8kOpf...@TK2MSFTNGP04.phx.gbl...

Mark Williams

unread,
May 23, 2006, 2:16:01 PM5/23/06
to
If you do SELECT * FROM [Some Table], and [Some Table] has a primary key,
won't the results always be sorted by the primary key?

That's what I meant.

-Mark Williams

--

Vern Rabe

unread,
May 23, 2006, 2:28:02 PM5/23/06
to
If you select all columns and all rows, it will typically sort by the
clustered index which is all too often on the primary key. But if the
clustered index is not on the PK, the results will typically be sorted on the
clustered indexed column. Try this:

CREATE TABLE test (col1 int PRIMARY KEY nonclustered, col2 int, col3
varchar(7000));
go
CREATE CLUSTERED INDEX X1 ON test(col2);
go
INSERT INTO test (col1, col2, col3)
SELECT 1, 300, REPLICATE('SQL', 2000)
UNION all
SELECT 2, 200, REPLICATE('SQL', 2000)
UNION ALL
SELECT 3, 100, REPLICATE('SQL', 2000);
go

SELECT * FROM test;

DROP TABLE dbo.test;

Tibor Karaszi

unread,
May 23, 2006, 2:28:04 PM5/23/06
to
Not necessarily, the order is determined by the execution plan.


"Mark Williams" <MarkWi...@discussions.microsoft.com> wrote in message

news:0D64DF81-C658-42F4...@microsoft.com...

NumbLock

unread,
May 24, 2006, 8:51:06 AM5/24/06
to
It should not be random since a clustered index physically orders the
data according to the sort order of the index. It should always come
back in sorted order unless they specifically use an Order by clause.

David Portas

unread,
May 24, 2006, 9:05:50 AM5/24/06
to
NumbLock wrote:
> It should not be random since a clustered index physically orders the
> data according to the sort order of the index. It should always come
> back in sorted order unless they specifically use an Order by clause.
>

That's just not so. For one thing, if the query is covered by a
non-clustered index then that may be used instead of a clustered scan.
For another, even if a clustered scan is used, the data will not
necessarily be returned in the cluster key order. The only way to
guarantee the order in a SELECT statement is to use ORDER BY.

--
David Portas, SQL Server MVP

Whenever possible please post enough code to reproduce your problem.
Including CREATE TABLE and INSERT statements usually helps.
State what version of SQL Server you are using and specify the content
of any error messages.

SQL Server Books Online:
http://msdn2.microsoft.com/library/ms130214(en-US,SQL.90).aspx
--

Tibor Karaszi

unread,
May 24, 2006, 9:22:41 AM5/24/06
to
> For one thing, if the query is covered by a
> non-clustered index then that may be used instead of a clustered scan.

> For another, even if a clustered scan is used, the data will not
> necessarily be returned in the cluster key order.

Yes, SQL Server can and will, if it finds a high fragmentation level, go by the IAM pages.

Yet another example is it the query is split up over several processors.


>> It should not be random <snip>

The term "random" is used loosely in this context (and I avoid it). SQL Server does not incur the
overhead of a random number generator to specify the order of each row. The term is used to say that
without ORDER BY, the rows can come back in any order the optimizer fits most efficient.


"David Portas" <REMOVE_BEFORE_R...@acm.org> wrote in message
news:1148475950.5...@j33g2000cwa.googlegroups.com...

Jim Underwood

unread,
May 24, 2006, 9:47:15 AM5/24/06
to
Yes, instead of Random I should have said "Non-Deterministic".

Personally, I try to use the simpler (if less technically accurate) terms.
Words with more than 2 syllables make my head hurt. Typing that first
sentence gave me a migraine.

"Tibor Karaszi" <tibor_please.n...@hotmail.nomail.com> wrote in

message news:O5v1iUz...@TK2MSFTNGP05.phx.gbl...

NumbLock

unread,
May 24, 2006, 11:35:17 AM5/24/06
to
Well... I may be wrong on that, but the whole purpose of a clustered
index is to order the data in the index.

From SSBOL:
A clustered index is particularly efficient on columns that are often
searched for ranges of values. After the row with the first value is
found using the clustered index, rows with subsequent indexed values are
guaranteed to be physically adjacent. For example, if an application
frequently executes a query to retrieve records between a range of
dates, a clustered index can quickly locate the row containing the
beginning date, and then retrieve all adjacent rows in the table until
the last date is reached. This can help increase the performance of this
type of query. Also, if there is a column(s) that is used frequently to
sort the data retrieved from a table, it can be advantageous to cluster
(physically sort) the table on that column(s) to save the cost of a sort
each time the column(s) is queried.

Note the last paragraph.
Further:

Before creating clustered indexes, understand how your data will be
accessed. Consider using a clustered index for:
Columns that contain a large number of distinct values.
Queries that return a range of values using operators such as BETWEEN,
>, >=, <, and <=.
Columns that are accessed sequentially.
Queries that return large result sets.

NumbLock

unread,
May 24, 2006, 12:10:52 PM5/24/06
to
One last bit from SSBOL:

Before creating clustered indexes, understand how your data will be
accessed. Consider using a clustered index for:

...

Columns that are frequently accessed by queries involving join or GROUP
BY clauses; typically these are foreign key columns. An index on the
column(s) specified in the ORDER BY or GROUP BY clause eliminates the
need for SQL Server to sort the data because the rows are already
sorted. This improves query performance.

David Portas

unread,
May 24, 2006, 12:15:47 PM5/24/06
to
NumbLock wrote:
> One last bit from SSBOL:
>
> Before creating clustered indexes, understand how your data will be
> accessed. Consider using a clustered index for:
>
> ...
>
> Columns that are frequently accessed by queries involving join or GROUP
> BY clauses; typically these are foreign key columns. An index on the
> column(s) specified in the ORDER BY or GROUP BY clause eliminates the
> need for SQL Server to sort the data because the rows are already
> sorted. This improves query performance.
>
>

That's all true. To be precise, the bit of your earlier post that was
wrong was this sentence:

"It should always come back in sorted order unless they specifically
use an Order by clause"

If you want to be sure the data is returned in a sorted order you still
need ORDER BY.

Jim Underwood

unread,
May 24, 2006, 12:17:45 PM5/24/06
to
This refers to physical storage and physical data access paths, but does not
guarantee the order in which results will be returned to the user. If SQL
Server chooses an access path utilizing the index, than you will get the
data back in that order, but only because SQL Server chose that particular
access path at the time. If you make a change to the query, if the
statistics change, or if anything else happens that changes the access path
SQL Server is using, your data will be returned in a different order.

The order of the results, when order by is not specified, are a side effect
of the physical access path chosen by the optimizer and can change with each
execution. The order is not determined by design, and depending on it will
eventually get you in trouble. A lot of folks found this when going from
SQL 2000 to 2005, when views with top 100 percent stopped returning rows in
the expected order. Even if certain queries seem to work, sooner or later
something will happen to change how the optimizer is processing the query
and your app will break.


"NumbLock" <pcg...@yahoo.com> wrote in message

news:OPgW$c0fGH...@TK2MSFTNGP05.phx.gbl...

NumbLock

unread,
May 24, 2006, 12:22:15 PM5/24/06
to
Allow me to point out *your* error:

For another, even if a clustered scan is used, the data will not
necessarily be returned in the cluster key order. The only way to
guarantee the order in a SELECT statement is to use ORDER BY.

It is one thing to be WRONG, it is quite another not to own up to it.

NumbLock

unread,
May 24, 2006, 12:31:28 PM5/24/06
to
Look guys. The whole purpose for a clustered index is to physically
order the data in the table. From that one can infer the following
(which I did)

You would create a clustered index on a column(s) on which you will be
querying. It goes without saying. If you have a clustered index on a
column on which you are querying, it will *always* come back sorted.
The assertion about multiple processors and execution plans does not
have any effect in the scenario. Now if you are querying on a number of
distinct columns it is possible that another index could be used. But
if you are doing a query on a range of values of one of the other
specific uses for a clustered index, it will chose the clustered index.
Maybe not always, but most of the time since it will use the most
appropriate index for the query. The assertion that you MUST use order
by to guarantee ordered results is simply not true as the BOL excerpts
have shown.

Tibor Karaszi

unread,
May 24, 2006, 12:33:13 PM5/24/06
to
Are you saying that below statement from David is incorrect?

> For another, even if a clustered scan is used, the data will not
> necessarily be returned in the cluster key order. The only way to
> guarantee the order in a SELECT statement is to use ORDER BY.

If so, can you elaborate?


"NumbLock" <pcg...@yahoo.com> wrote in message news:e8z9O30f...@TK2MSFTNGP04.phx.gbl...

David Portas

unread,
May 24, 2006, 12:42:31 PM5/24/06
to

"NumbLock" <pcg...@yahoo.com> wrote in message
news:e8z9O30f...@TK2MSFTNGP04.phx.gbl...

> Allow me to point out *your* error:
>
> For another, even if a clustered scan is used, the data will not
> necessarily be returned in the cluster key order. The only way to
> guarantee the order in a SELECT statement is to use ORDER BY.
>
> It is one thing to be WRONG, it is quite another not to own up to it.
>

That's no error.

Are you claiming that you can guarantee the order in a SELECT statement
without an ORDER BY? BOL states clearly that you can do no such thing.

NumbLock

unread,
May 24, 2006, 12:54:30 PM5/24/06
to
Yes I am saying that he is incorrect. In my previous post I stated that
if you create a clustered index on a column and you query on that
column, it will always come back sorted in the index order because the
data is physically ordered in the data pages. It is another matter if
you query on another column which is indexed. But if you are returning
a range of records, it would be better to use a clustered index on that
column instead of a standard index anyway. This is one of the main
reasons for a clustered index. I quote SSBOL again:

Under the Using Clustered Indexes topic of Books Online:

"A clustered index is particularly efficient on columns that are often
searched for ranges of values. After the row with the first value is
found using the clustered index, rows with subsequent indexed values are
guaranteed to be physically adjacent. For example, if an application
frequently executes a query to retrieve records between a range of
dates, a clustered index can quickly locate the row containing the
beginning date, and then retrieve all adjacent rows in the table until
the last date is reached. This can help increase the performance of this
type of query. Also, if there is a column(s) that is used frequently to
sort the data retrieved from a table, it can be advantageous to cluster
(physically sort) the table on that column(s) to save the cost of a sort
each time the column(s) is queried."

Look at the last sentence.

Also in the same topic... Last sentence:

"Before creating clustered indexes, understand how your data will be
accessed. Consider using a clustered index for:

Columns that contain a large number of distinct values.

Queries that return a range of values using operators such as BETWEEN,
>, >=, <, and <=.

Columns that are accessed sequentially.

Queries that return large result sets.

Columns that are frequently accessed by queries involving join or GROUP

BY clauses; typically these are foreign key columns. An index on the
column(s) specified in the ORDER BY or GROUP BY clause eliminates the
need for SQL Server to sort the data because the rows are already
sorted. This improves query performance."

NumbLock

unread,
May 24, 2006, 12:57:34 PM5/24/06
to
That is exactly what I am saying. Read my BOL excerpts. To verify:

Create a table with say a date column. Put a clustered index on that
column. Do a query on the column for a range of dates. IT will
*ALWAYS* come back ordered.

David Portas

unread,
May 24, 2006, 12:59:49 PM5/24/06
to
"NumbLock" <pcg...@yahoo.com> wrote in message
news:upeTQJ1f...@TK2MSFTNGP02.phx.gbl...

> Yes I am saying that he is incorrect. In my previous post I stated that
> if you create a clustered index on a column and you query on that column,
> it will always come back sorted in the index order because the data is
> physically ordered in the data pages.

Not true. Here's an example where the clustered index is not used, at least
that's what I find on SQL Server 2000 SP4 and on 2005 SP1. Of course I
can't guarantee you'll get the same results but there's probably a good
chance you will. I believe another scenario could arise with advanced
read-ahead (merry-go-round) scans, where the scan will not necessarily begin
at the top of the clustered index even if that index is used.

CREATE TABLE T1 (x INT PRIMARY KEY CLUSTERED, z CHAR(1) UNIQUE);
INSERT INTO T1 VALUES (1,'C');
INSERT INTO T1 VALUES (2,'B');
INSERT INTO T1 VALUES (3,'A');

SELECT x FROM T1;

Result:

x
-----------
3
2
1

(3 row(s) affected)

David Portas

unread,
May 24, 2006, 1:03:31 PM5/24/06
to
"NumbLock" <pcg...@yahoo.com> wrote in message
news:e1Q99K1f...@TK2MSFTNGP02.phx.gbl...

> That is exactly what I am saying. Read my BOL excerpts. To verify:
>
> Create a table with say a date column. Put a clustered index on that
> column. Do a query on the column for a range of dates. IT will *ALWAYS*
> come back ordered.
>

Not even with dates (YMMV).

CREATE TABLE T1 (x DATETIME PRIMARY KEY CLUSTERED, z CHAR(1) UNIQUE);
INSERT INTO T1 VALUES ('20050101','C');
INSERT INTO T1 VALUES ('20050102','B');
INSERT INTO T1 VALUES ('20050103','A');

SELECT x FROM T1;

x
------------------------------------------------------
2005-01-03 00:00:00.000
2005-01-02 00:00:00.000
2005-01-01 00:00:00.000

(3 row(s) affected)

NumbLock

unread,
May 24, 2006, 1:15:10 PM5/24/06
to
As I said, create a clustered index on a column where you are using a
where clause.

CREATE TABLE T1 (x INT PRIMARY KEY CLUSTERED, z CHAR(1) UNIQUE);
INSERT INTO T1 VALUES (1,'C');
INSERT INTO T1 VALUES (2,'B');
INSERT INTO T1 VALUES (3,'A');

SELECT x FROM T1 where x between 1 and 3;

DROP Table T1

This is the main reason for having a clustered index.

Tibor Karaszi

unread,
May 24, 2006, 1:18:58 PM5/24/06
to
> Also, if there is a column(s) that is used frequently to sort the data retrieved from a table, it
> can be advantageous to cluster (physically sort) the table on that column(s) to save the cost of a
> sort each time the column(s) is queried."
>
> Look at the last sentence.

I'm afraid you are mixing the logical structure vs. the physical structure. BOL states that id you
have ORDER BY that column, then having a clustered index can save a physical sort of the data in the
execution plan. It doesn't state that the rows will come back in that order if you *don't* have
ORDER BY.

I've seen such cases. Btw, here is a quote from Books Online, for the type of operator that will be
used for the type of query you mention:

The Clustered Index Scan operator scans the clustered index specified in the Argument column. When
an optional WHERE:() predicate is present, only those rows that satisfy the predicate are returned.
If the Argument column contains the ORDERED clause, the query processor has requested that the
output of the rows be returned in the order in which the clustered index has sorted it. If the
ORDERED clause is not present, the storage engine scans the index in the optimal way, without
necessarily producing sorted the output.

See that last point? This is what I referred to earlier (going by the IAM page instead of the linked
list).

The simple fact is that just because *you* haven't seen a case where the query isn't returned in the
order per the clustered index doesn't mean such doesn't exist...


"NumbLock" <pcg...@yahoo.com> wrote in message news:upeTQJ1f...@TK2MSFTNGP02.phx.gbl...

David Portas

unread,
May 24, 2006, 1:32:14 PM5/24/06
to
"NumbLock" <pcg...@yahoo.com> wrote in message
news:e$z3yU1fG...@TK2MSFTNGP05.phx.gbl...

> As I said, create a clustered index on a column where you are using a
> where clause.
>
> CREATE TABLE T1 (x INT PRIMARY KEY CLUSTERED, z CHAR(1) UNIQUE);
> INSERT INTO T1 VALUES (1,'C');
> INSERT INTO T1 VALUES (2,'B');
> INSERT INTO T1 VALUES (3,'A');
>
> SELECT x FROM T1 where x between 1 and 3;
>
> DROP Table T1
>
> This is the main reason for having a clustered index.
>

Still no guarantee of order. See Tibor's post. Certainly it is possible to
contrive special circumstances where you have this or that combination of
indexes to cause a specific execution plan to return data in order. It is
equally possible that such a precarious solution wouldn't work under some
future service pack or hotfix. This is what I mean by "no guarantee".
Logical order is always defined by an ORDER BY clause. BOL says:

"ORDER BY is important because relational theory specifies that the rows in

a result set cannot be assumed to have any sequence unless ORDER BY is

specified. ORDER BY must be used in any SELECT statement for which the order
of the result set rows is important."

So the documented behaviour is that ORDER BY is required if you require
sorted results. If you rely on some other undocumented behaviour then you
are trusting to luck rather than design.

NumbLock

unread,
May 24, 2006, 1:36:33 PM5/24/06
to
I will argue this one until somebody from MS tells me different. If you
have a clustered index that is being used on a column and you do a range
query on that column, it will come back ordered. That is the main
reason to use a clustered index... And... If you are using a clustered
index optimally, it would be the index that you query against.

"An index on the column(s) specified in the ORDER BY or GROUP BY clause
eliminates the need for SQL Server to sort the data because the rows are

already sorted. This improves query performance." This clearly implies
the data comes back sorted."

" rows with subsequent indexed values are guaranteed to be physically

adjacent." What does that tell you?

So you are saying that SQL server has the data in a specific order, but
it jumbles it up on purpose if you do not use an order by clause?

The only reason that records are in no particular order in a non
clustered index is because of page fragmentation and the way extents are
assigned. When you do an insert into a table with a clustered index,
the pages are physically reordered and pages are split/moved to
accommodate.

I've trusted this behavior for *years*. Unless you can show me a query
where it *does* *not* work like this, I will continue to believe the
data comes back ordered. Unless somebody from the SQL server team tells
me different. Then I will quietly eat my words.

If this is not so, then there are descrepancies in BOL.

NumbLock

unread,
May 24, 2006, 1:42:05 PM5/24/06
to
I can't see how you can consider my quotes from BOL to be undocumented.

When it clearly states that a sort will not be necessary since the data
is already in sorted order.

Kalen Delaney

unread,
May 24, 2006, 2:10:54 PM5/24/06
to
So you'll trust anyone from MS on this? What if we can get one of the
receptionists in the HR building to tell you?
There are developers on the SQL Team that know less about this one
particular area of the product than some of the people in this thread.
(I am having several people from the SQL Team at MS review chapters from
Inside SQL Server 2005. Sometimes their comments are completely
contradictory, and these are people who should know, right? Who should I
believe?)

How will YOU know who to believe?

I am not 'someone from MS', but I have played one on TV. :-)
And in many articles, books, webcasts, conference presentations and long
long meetings with people on the SQL team. And many long nights pouring over
DBCC PAGE output and query plans.

> "An index on the column(s) specified in the ORDER BY or GROUP BY clause
> eliminates the need for SQL Server to sort the data because the rows are
> already sorted. This improves query performance." This clearly implies
> the data comes back sorted."

This paragraph is indicating that you have an ORDER BY or GROUP BY.
It is saying that because there is an order to the data, no additional
sorting will have to be done. It does not imply that opposite, that without
the ORDER BY, the data will come back sorted.

> " rows with subsequent indexed values are guaranteed to be physically
> adjacent." What does that tell you?

Is this from BOL? If so, it is incorrect. It would not be the first time
there was a mistake in BOL. In fact you said this:

> If this is not so, then there are discrepancies in BOL.

You seem to be implying that this concept is unthinkable. There are many
errors, omissions and discrepancies in BOL. It is written by human beings.
In fact, they are so aware of their lack of perfection, there is a button on
every page for you to directly report problems.

If you read some of my articles in SQL Server Magazine, where I discuss
reading actual page dumps with DBCC PAGE, you can actually prove to yourself
that this is not true, and the data are rarely all PHYSICALLY adjacent. You
do not have to take my word, or Tibor's word, or anyone elses. See for
yourself.

> So you are saying that SQL server has the data in a specific order, but it
> jumbles it up on purpose if you do not use an order by clause?

I thought Tibor addressed this earlier. SQL Server does not incur the
overhead of any 'jumbling'.
If there is a clustered index, there is a likelihood that the data will come
back in the order of the index, but there is no guarantee. The clustered
index gives a logical ordering, with pointers allowing SQL Server to get to
the data in index order. But if there any fragmentation, following the
pointers to get the data in order may not be the most efficient way to get
the data if you do not NEED it to be in order. And without ORDER BY, you
are not indicating a need. Without an ORDER BY, SQL Server may decide to get
the data in actual physical order using the IAMs, instead of the logical
order of the pointers. Or there may be other steps it takes after the index
access, that affect the order of the result set. You can't know in advance.

If the data has a clustered index, using an ORDER BY will be very efficient,
and if you want the results ordered, adding the ORDER BY will not pose much,
if any, performance penalty. (That is what the first quoted paragraph above
is saying.) So why not just use it, so it's clear to you, anyone reading the
code, and to SQL Server, that you want the results ordered?

> I've trusted this behavior for *years*. Unless you can show me a query
> where it *does* *not* work like this, I will continue to believe the data
> comes back ordered.

You can believe all you want. Maybe all your queries will come back ordered.
But maybe someday, some crucial query won't. Then what will you do?
(I've been riding in cars as a passenger and driver for many years. I've
never been in an accident. Should I assume they don't happen and not wear a
seat belt? Since there is no harm in wearing one, I do.)
Again, if there is a clustered index, there is little or no overhead to
adding ORDER BY when you want the data returned in order of the clustered
key.


--
HTH
Kalen Delaney, SQL Server MVP
www.solidqualitylearning.com


"NumbLock" <pcg...@yahoo.com> wrote in message

news:%235J4vg1...@TK2MSFTNGP02.phx.gbl...

NumbLock

unread,
May 24, 2006, 2:31:56 PM5/24/06
to
You make several valid points with which I do not disagree. One thing
you did not mention is that a clustered index stores the entire row in
it's pages. These pages are physically ordered by the index. I am
saying the if you use a clustered index appropriately there will be no
need for another index to be used. I am talking about a range query on a
column with a clustered index. If you do a range query on another
column the clustered index will probably hurt the query more than it helps.

I do believe BOL does have errors/omissions. What I stated was all
quoted from BOL. Just take the bit about the guaranteed physically
adjacent part and plug into the search pane of BOL2K.

If what you are saying that the order of a clustered index is not
guaranteed to be sequential is true, then ms has been lying for years
not just in bol. I don't typically spend my time looking at dumps or
analyzing the physical structure of an MDF but I can tell you that
anybody I have spoken with or worked with knows that a clustered index
is physically ordered in the database. If that is not the case, why do
we need things like fillfactors and such? Is it a wicked ruse from
microsoft to disguise the fact that a clustered index is not really
clustered?

Now I am not a bigtime magazine editor, but I know what I have seen.
And I do believe that Microsoft would not sell a product claiming that a
clustered index is physically ordered when it is not. But I have been
wrong before and if the receptionist at ms says so then it must be true. :)

BTW are you married? :)

Jim Underwood

unread,
May 24, 2006, 2:34:18 PM5/24/06
to
You make one significant mistake here...

> I will argue this one until somebody from MS tells me different. If you
> have a clustered index that is being used on a column and you do a range
> query on that column, it will come back ordered. That is the main
> reason to use a clustered index...

This is not the reason to use a clustered index. The reason to use a
clustered index is so when you specify an order by on the indexed columns,
the optimizer does not have to do any extra work in order to put them in
order. This is not to avoid using order by, but to avoid extra work when
using order by. The way the SQL engine works, it just happens to use a
clustered index in the cases you are describing. This is not done because
SQL Server is trying to enforce the order of the results, it is merely a
byproduct of the optimizer trying to get the data as efficiently as
possible.

> "An index on the column(s) specified in the ORDER BY or GROUP BY clause
> eliminates the need for SQL Server to sort the data because the rows are
> already sorted. This improves query performance." This clearly implies
> the data comes back sorted.

Again, the rows are only sorted if the optimizer chooses the clustered
index, which it is likely to do if there is an order by on the same columns
in the clustered index. No where does it say you don't need to use an order
by, but rather if you are using an order by SQL will be able to use the
clustered index to avoid the extra overhead of performing a separate sort.

Granted, the example query you gave works, and the rule you gave that
selecting from a single table with a where clause on the clustered index
columns also seems to work. It is possible that it always works on SQL 2000
and sql 2005. However, there is nothing to say that the next service pack
will not change how the optimizer uses clustered indexes, breaking this
"functionality".

The biggest problem is that this "functionality" only works in certain
circumstances and is completely dependent on the choices that the optimizer
makes. With the simplest queries you may be able to depend on it, but with
more complicated queries (with joins or criteria on columns not in the
clustered index) it will fail often enough.

It sounds like your main argument is "if you write your query a certain way
you don't need to include the order by clause". If you include the order by
clause you will never have to worry about writing your query a certain way,
and no change to the optimizer will every break your queries.


"NumbLock" <pcg...@yahoo.com> wrote in message

news:%235J4vg1...@TK2MSFTNGP02.phx.gbl...

Stu

unread,
May 24, 2006, 2:43:52 PM5/24/06
to
Well, how about this?

CREATE TABLE T1 (x INT PRIMARY KEY CLUSTERED, z CHAR(1) UNIQUE);
INSERT INTO T1 VALUES (1,'C');
INSERT INTO T1 VALUES (2,'B');
INSERT INTO T1 VALUES (3,'A');

SELECT x FROM T1
where x between 1 and 3

AND z between 'a' and 'c';

DROP Table T1

I got

x
3
2
1

Yet, I used the clustered index column as part of my WHERE clause. I
also happened to use a better covering index, so the optimizer chose a
sort order that did not match my clustered index.

I don't think that anyone is challending your interpretation of BOL in
terms of the physical storage and order of the data; I think (as do
others, obviously) that you are mistaken in terms of how that physical
storage affects the return of data. In short, no ORDER BY clause means
that you cannot guarantee your data will be returned in the order of
the clustered index.

Stu

NumbLock

unread,
May 24, 2006, 2:47:48 PM5/24/06
to
Well, I have had great fun arguing with you all over this. The original
poster is long gone by now I am sure. What I am saying (and it is
supported by BOL) is that you should use a clustered index on a range
query that is going to be returned in a specific order. You can take it
out to the nth degree if you want to, but until you show me a query
which behaves otherwise, I won;t belive you.

If you want to be Anal like some programmers are, sure, go ahead and use
an order by clause on a column which is already ordered. It's just a
little more wear and tear on your fingers. :)

NumbLock

unread,
May 24, 2006, 2:53:31 PM5/24/06
to
I do not dispute the fact that an index on another column will or can
have any effect. As I said, it goes without saying. If you had put
the clustered index on the char column, the same query returns

CREATE TABLE T1 (x INT, z CHAR(1) PRIMARY KEY CLUSTERED);


INSERT INTO T1 VALUES (1,'C');
INSERT INTO T1 VALUES (2,'B');
INSERT INTO T1 VALUES (3,'A');

SELECT * FROM T1


where x between 1 and 3
AND z between 'a' and 'c';

DROP Table T1

3 A
2 B
1 C

Stu

unread,
May 24, 2006, 2:57:36 PM5/24/06
to
A) That's not the same query.

B). The fact that you don't dispute the fact that an index on another
column is quite intriguing because that seems to be EXACTLY the point
that David and others have been attempting to make.

Stu

NumbLock

unread,
May 24, 2006, 3:07:31 PM5/24/06
to
How do you figure it is not the same query???? I am selecting *, more
of a reason for SQL Server to be selective.

My. You are easily intrigued. Read my previous posts about a range
query on a clustered index. The other gentlemen have made various
statements. Some I agree with, some I don't

If it is not the same query then try it with a composite key for x and
z. It comes back in index order. But you already knew that because the
God's of the covered index have spoken to you about it, huh?

Kalen Delaney

unread,
May 24, 2006, 3:05:02 PM5/24/06
to
I have spent considerable time studying page dumps, and I guarantee that the
data is not physically contiguous, it is logically contiguous.

> If what you are saying that the order of a clustered index is not
> guaranteed to be sequential is true, then ms has been lying for years not
> just in bol.

Again, MS is many people. The engineers who actually work with the storage
engine have not ever said the data is stored PHYSICALLY in order on the
disk. It is guaranteed to be logically sequential, in that there are
pointers to allow SQL Server to retrieve the data in sorted order. But
without ORDER BY, there is no guarantee that even if the data was retrieved
from disk sorted, that it will be presented to you sorted.

The fact that the clustered index contains the entire row in its leaf level
is irrelevant. The rows are stored logically in order, but not guaranteed to
be physically in order.

> And I do believe that Microsoft would not sell a product claiming that a
> clustered index is physically ordered when it is not.

Just think about it...Do you think that if you have 1 million pages in a
table, and you have to insert one row in the middle of a full page, that SQL
Server will physically move half a million pages just to keep the data
physically in order? Inserts would take forever, and they don't. That would
be far worse for Microsoft than a mere misunderstanding about the difference
between logically and physically sorted.

>why do we need things like fillfactors and such?

In the above insert example, inserting into a full page requires a page
split and readjustment of pointers, but it does not require moving of all
the pages that came after the full one. Lots of splitting is more expensive
than no splitting, and a low fillfactor can help delay splitting.

> Is it a wicked ruse from microsoft to disguise the fact that a clustered
> index is not really clustered?

Nothing wicked about it. The rows are logically clustered. Immediately after
building an index, the rows and pages will be as physically contiguous as
possible, but if there is not enough contiguous space in the file, the
extents for the index will be distributed throughout the file. And there is
always a chance that SQL Server's data files will be fragmented on the
physical disk. So what do you really mean by 'physical', anyway?

I think the design is a good one. If SQL Server had to constantly guarantee
physical order to the rows in a clustered index, performance of everything
else would be abysmal. In those cases where you need the data to be as
physically contiguous as possible, make sure your indexes are as
unfragmented as possible.

http://www.microsoft.com/technet/prodtechnol/sql/2000/maintain/ss2kidbp.mspx

>> I am
> saying the if you use a clustered index appropriately there will be no
> need for another index to be used. <<

This is probably true. But there is no guarantee the result set will be in
order without the ORDER BY.

> BTW are you married? :)

That is a little forward, since you've never even posted your name. :-)
But please see: http://www.bookpool.com/ct/154

--
HTH
Kalen Delaney, SQL Server MVP
www.solidqualitylearning.com


"NumbLock" <pcg...@yahoo.com> wrote in message

news:%23phbs$1fGHA...@TK2MSFTNGP03.phx.gbl...

SQL Menace

unread,
May 24, 2006, 3:14:45 PM5/24/06
to
Mmmmm, 4 kids and still managing to do all this
I have twins due in about 6 weeks (in addition to a 2 year old, who is
not terrible (yet)) and I am already starting my panic mode ;-(


Denis the SQL Menace
http://sqlservercode.blogspot.com/

Kalen Delaney

unread,
May 24, 2006, 3:16:48 PM5/24/06
to
It is not being anal. It is not relying on behavior that is not guaranteed
and protecting yourself against future changes.
Here's an example, that relates to what Jim said about future changes in the
optimizer.

In SQL 6.5, when you used the a GROUP BY, SQL Server had to physically sort
the data to form the groups, so the results came back in sorted order by the
grouping column. Many people assumed that meant that GROUP BY included the
ORDER BY functionality, and never bothered to include ORDER BY in their
queries. Then when those people upgraded to SQL Server 7, and tried to run
their same application with the same GROUP BY queries they were in for a
shock. Sometimes their data would come back in order, and sometimes it
wouldn't. Because the optimizer in SQL 7/2000/2005 now has two different
ways to do GROUP BY, one that requires sorted data, and one that doesn't.

The only way to guarantee the order of your results is with ORDER BY.
Period.

But of course, you can do what you like. It sounds like you've just been
lucky so far, but luck doesn't last forever.
No one here can force you to believe us, or to protect yourself.

--
HTH
Kalen Delaney, SQL Server MVP
www.solidqualitylearning.com

"NumbLock" <pcg...@yahoo.com> wrote in message

news:ezwIkI2f...@TK2MSFTNGP03.phx.gbl...

NumbLock

unread,
May 24, 2006, 3:22:04 PM5/24/06
to
Darn. He is a lucky guy. There is a shortage of SQL aware women on
this planet. :)

When someone says that data is physically sorted in a particular order
on disk, I do believe them. There is no ambiguity here when the word
physical is used. And the fact that the index pages contain the entire
row supports the fact that the data would come back in the index order.
What would the purpose of a clustered index serve.

I have always been taught that a clustered index does dramatically hurt
the insertion of data in many cases just for the reasons you specify.
But that goes along with the appropriate use of a clustered index. If
you are doing a lot of inserts, it might not be the right choice. If
you are doing a lot of selects (especially when they are ordered and
especially for ranges of data) a clustered index is a good choice. I
realize that I have not seen it all. And I have certainly been wrong
before. I am just curious if anyone can show me a query where it comes
back differently when a range is selected against a column with a
clustered index on it. Maybe others are right about SMP machines but it
does conflict with BOL at least what I've read.

BTW my name is Galen, Kalen. :)

Kalen Delaney

unread,
May 24, 2006, 3:19:38 PM5/24/06
to
Mine are a bit older. I didn't start writing books until the youngest was in
school.

But you're in for a treat... Think of it as an adventure, and
congratulations!!

--
HTH
Kalen Delaney, SQL Server MVP
www.solidqualitylearning.com


"SQL Menace" <denis...@gmail.com> wrote in message
news:1148498085.1...@g10g2000cwb.googlegroups.com...

David Portas

unread,
May 24, 2006, 3:25:29 PM5/24/06
to
"NumbLock" <pcg...@yahoo.com> wrote in message
news:u$M81j1f...@TK2MSFTNGP02.phx.gbl...

>I can't see how you can consider my quotes from BOL to be undocumented.
>
> When it clearly states that a sort will not be necessary since the data is
> already in sorted order.
>

As Kalen has already explained, that quote specifically refers to the
condition where an index is specified on the column(s) in the ORDER BY
clause. If you do NOT specify ORDER BY (or maybe GROUP BY) then the
situation is different because the clustered index may be scanned in
physical order instead of cluster key order.

NumbLock

unread,
May 24, 2006, 3:35:57 PM5/24/06
to
This horse is long since dead by now. It is inferring that you have
used an order by clause on a column with a clustered index. It is
saying "if you use an order by clause the data won't have to be sorted
because it comes back in sorted order already." Are you saying that It
somehow knows that you are going to use an order by clause and decides
to return the data in the proper order? But for some reason you forget
the order by clause it can tell the difference?

I don't mean to be hostile. I realize this behavior could change in the
future however that goes against all a clustered index is supposed to
stand for. I am just a sucker for a good argument. I apologize if I
have offended anyone.

Gert-Jan Strik

unread,
May 24, 2006, 3:35:02 PM5/24/06
to
NumbLock wrote:
>
> I will argue this one until somebody from MS tells me different. If you
> have a clustered index that is being used on a column and you do a range
> query on that column, it will come back ordered. [snip]

>
> I've trusted this behavior for *years*. Unless you can show me a query
> where it *does* *not* work like this, I will continue to believe the
> data comes back ordered. Unless somebody from the SQL server team tells
> me different. Then I will quietly eat my words.

I am not from Microsoft, but I sure have been around when it comes to
SQL-Server. And I can tell you: you are wrong!

As mentioned by many other experts in this newsgroup, and in BOL, the
only way to guarantee a sorted result is to specify the proper ORDER BY
clause.

So you ask us to disprove your unfounded theory that the results of a
query without ORDER BY clause will always be sorted, as long as the
query has a where clause that uses the (clustered) indexed column?

Then I suppose the query

select id % 7,count(*)
from Test
where id between 2 and 78
group by id % 7

will qualify if there is a clustered index on Test.id, right?

Well, if I run the batch below on my system (a SMP enabled server with
SQL-Server 2000 Enterprise Edition), this query will return the
following resultset:

----------- -----------
0 90112
3 90112
6 90112
2 90112
5 90112
1 90112
4 90112

(7 row(s) affected)

If you want consistent results, then you'd better throw your theory out
the window...

Gert-Jan


-------------------------------------------
create table Test (id int not null,filler char(500) not null)
create clustered index IX_Test on Test(id)
go

insert into Test values (1,'filler')
insert into Test values (2,'filler')
insert into Test values (3,'filler')
insert into Test values (4,'filler')
insert into Test values (5,'filler')
insert into Test values (6,'filler')
insert into Test values (7,'filler')
insert into Test values (8,'filler')
insert into Test values (9,'filler')
insert into Test values (10,'filler')

insert into Test select id+10,'filler' from Test
insert into Test select id+20,'filler' from Test
insert into Test select id+40,'filler' from Test

declare @i int
set @i=13
while @i>0
begin
set @i=@i-1

insert into Test
select id,'filler'
from Test
end
go

/*
|--Compute Scalar(DEFINE:([Expr1003]=Convert([globalagg1005])))
|--Parallelism(Gather Streams)
|--Hash Match(Aggregate, HASH:([Expr1002]),
RESIDUAL:([Expr1002]=[Expr1002])
DEFINE:([globalagg1005]=SUM([partialagg1004])))
|--Parallelism(Repartition Streams, PARTITION
COLUMNS:([Expr1002]))
|--Hash Match(Partial Aggregate,
HASH:([Expr1002]), RESIDUAL:([Expr1002]=[Expr1002])
DEFINE:([partialagg1004]=COUNT(*)))
|--Compute
Scalar(DEFINE:([Expr1002]=[Test].[id]%7))
|--Clustered Index
Seek(OBJECT:([somedb].[dbo].[Test].[IX_Test]), SEEK:([Test].[id] >= 2
AND [Test].[id] <= 78) ORDERED FORWARD)
*/

select id % 7,count(*)
from Test
where id between 2 and 78
group by id % 7
go

drop table Test

NumbLock

unread,
May 24, 2006, 3:44:39 PM5/24/06
to
Gee Gert. Somehow you think the aggregate count(*) will have no effect?

David Portas

unread,
May 24, 2006, 3:44:34 PM5/24/06
to
NumbLock wrote:
> Are you saying that It
> somehow knows that you are going to use an order by clause and decides
> to return the data in the proper order? But for some reason you forget
> the order by clause it can tell the difference?

Exactly so. That's what the optimizer is for.

> I don't mean to be hostile. I realize this behavior could change in the
> future however that goes against all a clustered index is supposed to
> stand for.

Does it? I think not because MS has never said that clustered indexes
affect logical query results. They are an optimization feature is all.
That is what they stand for.

BTW I recommend Kalen's books of course if you want more on the gritty
details of clustered indexes.

NumbLock

unread,
May 24, 2006, 3:51:29 PM5/24/06
to
Your query is nothing like I've been describing. An aggregate and a
group by will certainly make a difference. Show me a query where a
range is used on a column with a clustered index that does not come back
in index order.

But I can see that this group is reserved for the *experts* out there so
I will keep my comments to myself from now on. I am still waiting for
the *experts* to prove me wrong in the case I have described.

I have been around sql server a good while, too Gert. If I am proved
wrong, I will take it like a man. But don't go reaching for straws like
you are clearly doing.

NumbLock

unread,
May 24, 2006, 3:55:14 PM5/24/06
to
So the optimizer can read your mind? What it says is that the data is
already ordered if you use an order by. How much clearer can that be?

If you do not use an order by it is somehow going to jumble the rows?

The fact that it is already ordered should illuminate this issue.

Gert-Jan Strik

unread,
May 24, 2006, 4:04:27 PM5/24/06
to
[snip]

I don't understand. What are you saying? That my example should not have
an aggregate?

I thought you said that if the clustered index was used to satisfy a
range scan, then the output would magically and automatically be sorted
by the clustered index order? The example shows that this is not always
the case. It shows that the optimizer makes no effort to sort the
resultset if it happens to loose the order somewhere during execution.
In other words: it disproves your theory.

Gert-Jan

NumbLock

unread,
May 24, 2006, 4:06:04 PM5/24/06
to
Did you read this? How can you possibly support your argument in light
of this? Perhaps it is a typo but it is an awfully detailed typo in
that case.

"A clustered index is particularly efficient on columns that are often
searched for ranges of values. After the row with the first value is
found using the clustered index, rows with subsequent indexed values are
guaranteed to be physically adjacent. For example, if an application
frequently executes a query to retrieve records between a range of
dates, a clustered index can quickly locate the row containing the
beginning date, and then retrieve all adjacent rows in the table until
the last date is reached. This can help increase the performance of this

type of query. Also, if there is a column(s) that is used frequently to

sort the data retrieved from a table, it can be advantageous to cluster
(physically sort) the table on that column(s) to save the cost of a sort
each time the column(s) is queried"

Note the word Physically in "Physically Sort" I do not see the word
logical mentioned anywhere here.

David Portas

unread,
May 24, 2006, 4:08:32 PM5/24/06
to
NumbLock wrote:
> So the optimizer can read your mind? What it says is that the data is
> already ordered if you use an order by. How much clearer can that be?
>
> If you do not use an order by it is somehow going to jumble the rows?
>
> The fact that it is already ordered should illuminate this issue.
>

Huh? The optimizer reads the query not your mind. If the query doesn't
have ORDER BY then it can safely scan the data in physical order rather
than cluster key order. You are repeating the same points that Kalen
has already addressed. I'm just going to refer you again to her book
"Inside SQL Server". You'll have to wait for her 2005 volume but Inside
2000 is a must-read.

NumbLock

unread,
May 24, 2006, 4:18:07 PM5/24/06
to
It does not disprove my theory. I stated that if a clustered index is
used on a column and a range query is performed on that column it would
come back ordered. Certainly other factors such as grouping and
aggregates will effect the usage of the clustered index as well as if
you are querying on a column that is not part of the clustered index.

You can talk all the terminology you want, but it doesn't change the
fact of what I said. If this is incorrect from books online, then I am
clearly wrong. And I will shut up. I invite you to read this carefully:

"A clustered index is particularly efficient on columns that are often
searched for ranges of values. After the row with the first value is
found using the clustered index, rows with subsequent indexed values are
guaranteed to be physically adjacent. For example, if an application
frequently executes a query to retrieve records between a range of
dates, a clustered index can quickly locate the row containing the
beginning date, and then retrieve all adjacent rows in the table until
the last date is reached. This can help increase the performance of this

type of query. Also, if there is a column(s) that is used frequently to

sort the data retrieved from a table, it can be advantageous to cluster
(physically sort) the table on that column(s) to save the cost of a sort
each time the column(s) is queried"

Gert-Jan Strik wrote:

Tibor Karaszi

unread,
May 24, 2006, 4:16:45 PM5/24/06
to
> Note the word Physically in "Physically Sort" I do not see the word logical mentioned anywhere
> here.

Let's look at that BOL sentence again:

> Also, if there is a column(s) that is used frequently to sort the data retrieved from a table, it
> can be advantageous to cluster (physically sort) the table on that column(s) to save the cost of a
> sort each time the column(s) is queried"

" if there is a column(s) that is used frequently to sort..."

If you frequently have an ORDER BY over a column...


"it can be advantageous to cluster (physically sort) the table on that column(s) to save the cost
of a sort each time the column(s) is queried"

SQL Server doesn't have to do a sort operation for the query execution to support the ORDER BY you
have in the query.

BOL use the term "physically sort" incorrect, btw. Or rather, it all depends on what abstraction
level you want to be. Because of page splits, you can have external fragmentation, so the data isn't
sorted physically anymore (of you by physically mean the database file).

--
Tibor Karaszi, SQL Server MVP
http://www.karaszi.com/sqlserver/default.asp
http://www.solidqualitylearning.com/


"NumbLock" <pcg...@yahoo.com> wrote in message news:emqrS02f...@TK2MSFTNGP04.phx.gbl...

NumbLock

unread,
May 24, 2006, 4:21:58 PM5/24/06
to
And what I am saying is that according to everything I have read,
physical order IS index order on a clustered index. Read my quote from
bol. It is clear that if you claim to be experts, a little old guy like
me won't shake your thinking. But if you READ the SQL BOL Excerpt, you
can arrive at no other conclusion. If you refuse to see the facts as
presented, then that is your own problem. I am saying that BOL is
saying that IF you use an order by clause on a clustered index column it
will not need to be sorted because it comes back sorted already.

I;ve had enough of this. You *experts* can talk your terminology all
you want. I am *not* an expert and never claimed to be. But I can read
and I do believe what I read in BOL.

David Portas

unread,
May 24, 2006, 4:27:01 PM5/24/06
to
NumbLock wrote:
> And what I am saying is that according to everything I have read,
> physical order IS index order on a clustered index. Read my quote from
> bol. It is clear that if you claim to be experts, a little old guy like
> me won't shake your thinking. But if you READ the SQL BOL Excerpt, you
> can arrive at no other conclusion. If you refuse to see the facts as
> presented, then that is your own problem. I am saying that BOL is
> saying that IF you use an order by clause on a clustered index column it
> will not need to be sorted because it comes back sorted already.
>
> I;ve had enough of this. You *experts* can talk your terminology all
> you want. I am *not* an expert and never claimed to be. But I can read
> and I do believe what I read in BOL.
>

BOL is plain wrong about physical sorting. It ought to be corrected but
you should also read better books.

Amazingly, I just got hold of the "TSQL Querying" volume of the new
"Inside SQL Server 2005". Starting on page 124 it describes ordered and
unordered scans of a clustered index, with a diagram included! You
should like this book because Lubor Kollar is a contributor and he does
work for MS and actually developed much of the engine functionality.

http://www.amazon.com/gp/product/0735623139/sr=8-4/qid=1148501475/ref=pd_bbs_4/103-1836600-8051002?%5Fencoding=UTF8

Kalen Delaney

unread,
May 24, 2006, 4:25:40 PM5/24/06
to
Galen

There are experts answering questions here. Maybe you can learn something.

What kind of proof do you want? We don't have access to your system, your
database and your disks. How do you prove that something might happen?
And you have not responded to my comment about future versions doing things
differently. Maybe right now with your data on the current version, you will
always get the data back in sorted order when you select a range on a column
with a clustered index. If I had to place a bet one way or another, I would
say that yes, it WILL come back in order. But that is not a guarantee.

What if the optimizer works differently in the next version, or in a service
pack? MS is under no obligation to make things backward compatible that they
never promised in the first place. They have said that the only way to
guarantee sorted results is to use ORDER BY.

You sound like someone saying he doesn't have to wear a helmet when he rides
a motorcycle, because he'll never be in an accident. How do you prove to him
that wearing a helmet is a good idea? You can point out all the other
accidents, but he still says "it won't happen to me".

--
HTH
Kalen Delaney, SQL Server MVP
www.solidqualitylearning.com

"NumbLock" <pcg...@yahoo.com> wrote in message

news:uRLcJs2f...@TK2MSFTNGP04.phx.gbl...

Jim Underwood

unread,
May 24, 2006, 4:27:05 PM5/24/06
to
I will be very surprised if anyone can come up with an example where
select col1 from table1
or
select * from table 1 where col1 between @start and @end
(assuming a clustered index exists on col1, of course)
does not bring back the results ordered by col1.
I will be equally as surprised if this NEVER changes due to service
packs/upgrades to the optimizer.

I believe that in the very simple scenarios you mentioned that you can (on
the current service packs of 200 and 2005) rely on this functionality.

If SQL server ever determines, for any reason, that the clustered index is
not the most efficient way to get the rows, this will break.
Your argument, as I understand it, is that SQL will always use the clustered
index in the above queries, and that this will never change?

If we expect it to change, then relying on it foolhardy at best.

If we believe it will only work in very simple, and specific circumstances,
then I would argue that typing "order by columnname" takes less time and
energy than considering if your query matches these requirements or not. It
also guarantees that no change will ever break it, which most programmers
would consider important enough to type that one extra line. Lastly, it
prevents those embarrassing errors where the system breaks because one
programmer did not notice that another programmer had relied on an implicit
sort when adding that ever so important where clause on a different column.

You seem to be saying that you should not explicitly specify your order by
if the system will (by chance) do it implicitly. Not specifying how you
want the computer to handle something, because it happens to do it by
default, is seldom, if ever, a wise choice. This approach is responsible
for more problems than I can remember. While this is forgivable when the
developer does not know that a requirement exists, it is not forgivable when
the developer knew the requirement existed, but purposely left it out of the
code just to save a single line of typing.

"NumbLock" <pcg...@yahoo.com> wrote in message
news:uRLcJs2f...@TK2MSFTNGP04.phx.gbl...

Gert-Jan Strik

unread,
May 24, 2006, 4:32:46 PM5/24/06
to
I assumed my example was a proper example. You are now saying your
theory has a more 'narrow' scope. Fine.

The point is, that if you do not specify an ORDER BY clause, then the
optimizer will not automatically add the "ordered" indication to the
physical operator in the execution tree (at least not always), and it
will not add a sorting operator anywhere at the end (to explicitely sort
the result). This leads to the fact that SQL Server will not guarantee
you the output order.

If I understand you correctly you are saying, that in practice a query
that:
- accesses only one table that has only one index (which is clustered)
- has a WHERE clause that filters on the clustered index column
- contains no aggregates
- has no ORDER BY clause
will always return its rows in the order of the clustered index.

Although this order is very likely, the fact remains, that is order is
not guaranteed. It is very hard to get a proper example for this limited
scenario, but if the storage engine happens to hitch on a merry-go-round
scan for your query, then the results will most likely be out of order.

It begs the question: why would you not want to add an ORDER BY clause
if the order is important? Why would you want to risk getting incorrect
order?

Gert-Jan

NumbLock wrote:
>
> Your query is nothing like I've been describing. An aggregate and a
> group by will certainly make a difference. Show me a query where a
> range is used on a column with a clustered index that does not come back
> in index order.
>
> But I can see that this group is reserved for the *experts* out there so
> I will keep my comments to myself from now on. I am still waiting for
> the *experts* to prove me wrong in the case I have described.
>
> I have been around sql server a good while, too Gert. If I am proved
> wrong, I will take it like a man. But don't go reaching for straws like
> you are clearly doing.
>
> Gert-Jan Strik wrote:

[snip]


> > Then I suppose the query
> >
> > select id % 7,count(*)
> > from Test
> > where id between 2 and 78
> > group by id % 7
> >
> > will qualify if there is a clustered index on Test.id, right?

[snip]

Jim Underwood

unread,
May 24, 2006, 4:43:31 PM5/24/06
to

"NumbLock" <pcg...@yahoo.com> wrote in message
news:%23GXRej2...@TK2MSFTNGP02.phx.gbl...

> Are you saying that It
> somehow knows that you are going to use an order by clause and decides
> to return the data in the proper order? But for some reason you forget
> the order by clause it can tell the difference?
>
The optimizer looks at the entire query in order to determine the execution
plan. If you have an order by clause on a column with a clustered index,
then the optimizer knows that the most efficent way to get the data and sort
it is to retrieve it via the (already sorted) clustered index.

Consider the following query:
(Table1 has a clustered index on Col1, no index on any other columns)

Select Col1, Col2, Col3 from table1 where col1 between 1 and 100 order by
Col1
path option 1: full table scan, filter, sort by col1
path option 2: clustered index seek based on filter criteria, sort by col1
path option 3: clustered index seek based on filter criteria
no need to sort because the clustered index already has the data
organized as we need it

In the first example, option one is the least efficent. we look at more
rows because we are not using an index, then we filter every row to
determine whether or not to keep it, then we sort the results.
Option two is better. We use the index to retrieve only the rows that match
the criteria, without wasting time on the rows that dont. Then we sort the
results.
Option 3 is clearly the best. Use the clustered index to retrieve the
results based on the filter, dont waste time looking at rows that do not
match the criteria. Because the index is already sorted, we don't waste
time on a seperate sort algorithm either.

The optimizer considers the options, and knows that option 3 is by far the
most efficent, and chooses this option.

The optimizer will not choose a clustered index simply because it likes to
have the data sorted. This simply happens to be the most efficent way for
it to retrieve the results. You seem to think that this is done
intentionally for sorting purposes, but it is not. The fact that adding any
other criteria, join, or function to your query causes this to break should
be proof that results are not guarenteed in any particular order.


Dan

unread,
May 24, 2006, 5:26:47 PM5/24/06
to
Here are some examples where the rows are not produced in the order of the
clustered index when ORDER BY is not used. These are queries on columns that
have a clustered index.


CREATE TABLE TestStuff
(
-- this column is clustered and this is the column queried
ID uniqueidentifier CONSTRAINT UNQ1 UNIQUE CLUSTERED,
-- this column is not clustered
Data INT PRIMARY KEY NONCLUSTERED
)

SET NOCOUNT ON

DECLARE @Ind INT
SET @Ind = 100000
WHILE @Ind > 0
BEGIN
SET @Ind = @Ind - 1
INSERT INTO TestStuff2 VALUES (newid(), @Ind)
END


SELECT ID FROM TestStuff

-- guids are not in order
------------------------------------ -----------
A5CD2D95-3AFB-4A43-8554-7AC81E481516
48BF4B06-E554-49F3-8148-8F1E68F7D8B2
124CC9B9-844D-4375-B343-4E0E72992993
6C6AD7BC-045C-408D-AC52-627DB3F6CCFE
07D41296-4A32-4F2B-B550-0A9279794182
97CA9105-4EB4-4E66-A945-53505EA4433B
54EDAA9F-8E91-4F03-9DA5-6295105562C8
B986E317-BD61-4023-BFD8-7AD3912443DF
281E566F-7D80-443B-8645-64E6F5654639
5D522926-18A8-46B0-AFE0-1823F4634AAB
...

-- now use ORDER BY and the guids come out in order
-- note it is the right end of the GUID that determines the order

SELECT ID FROM TestStuff
ORDER BY ID

-- guids are in order
------------------------------------ -----------
55EA754C-E344-4D79-95F1-0000D558BA20
736DC313-06D1-486C-BE3B-00019C8E514C
553922FD-759F-44FD-B6EE-000205DF3FDE
3F678767-AEBB-400B-8946-00020D308672
2628EB81-A632-4C7F-B323-00026066CFAA
FF4CD6F4-419E-43E1-913F-000261BE45BE
3864C4CF-E164-4B10-9880-00027F5383A2
9E1D9258-DB74-47FE-B858-0002AC2F243C
E5884DCD-C836-4202-95F9-0003A563F920
6AAE6E38-4530-4931-9956-0003B716C900
171DD6F3-C4FE-419F-A25B-00061B80A8CD
400BB5FE-E4A1-42D0-B38D-00071F631F09
BFFABF80-845F-46BA-8386-0007C3AAD2E4
A7FB3B53-DE13-40DA-986E-0007C8F7F945
...


Here is a query that uses BETWEEN on the column that has a clustered index.
Note that the rows do not come out in ID order unless ORDER BY is used

SELECT * FROM TestStuff
WHERE ID BETWEEN '55EA754C-E344-4D79-95F1-0000D558BA10'
AND
'97BF22EB-6C5C-4616-A894-FFFFE65614CA'


ID Data
------------------------------------ -----------
A5CD2D95-3AFB-4A43-8554-7AC81E481516 0
48BF4B06-E554-49F3-8148-8F1E68F7D8B2 1
124CC9B9-844D-4375-B343-4E0E72992993 2
6C6AD7BC-045C-408D-AC52-627DB3F6CCFE 3
07D41296-4A32-4F2B-B550-0A9279794182 4
97CA9105-4EB4-4E66-A945-53505EA4433B 5
54EDAA9F-8E91-4F03-9DA5-6295105562C8 6
B986E317-BD61-4023-BFD8-7AD3912443DF 7
...

SELECT * FROM TestStuff
WHERE ID BETWEEN '55EA754C-E344-4D79-95F1-0000D558BA10'
AND
'97BF22EB-6C5C-4616-A894-FFFFE65614CA'
ORDER BY ID


ID Data
------------------------------------ -----------
55EA754C-E344-4D79-95F1-0000D558BA20 59231
736DC313-06D1-486C-BE3B-00019C8E514C 41296
553922FD-759F-44FD-B6EE-000205DF3FDE 74878
3F678767-AEBB-400B-8946-00020D308672 2221
2628EB81-A632-4C7F-B323-00026066CFAA 40496
FF4CD6F4-419E-43E1-913F-000261BE45BE 43519
...


Dan


> Look guys. The whole purpose for a clustered index is to physically
> order the data in the table. From that one can infer the following
> (which I did)
>
> You would create a clustered index on a column(s) on which you will be
> querying. It goes without saying. If you have a clustered index on a
> column on which you are querying, it will *always* come back sorted.
> The assertion about multiple processors and execution plans does not
> have any effect in the scenario. Now if you are querying on a number
> of
> distinct columns it is possible that another index could be used. But
> if you are doing a query on a range of values of one of the other
> specific uses for a clustered index, it will chose the clustered
> index.
> Maybe not always, but most of the time since it will use the most
> appropriate index for the query. The assertion that you MUST use
> order
> by to guarantee ordered results is simply not true as the BOL excerpts
> have shown.
> NumbLock wrote:
>> Allow me to point out *your* error:
>>
>> For another, even if a clustered scan is used, the data will not
>> necessarily be returned in the cluster key order. The only way to
>> guarantee the order in a SELECT statement is to use ORDER BY.
>>
>> It is one thing to be WRONG, it is quite another not to own up to it.


>>
>> David Portas wrote:
>>
>>> NumbLock wrote:
>>>

>>>> One last bit from SSBOL:
>>>>
>>>> Before creating clustered indexes, understand how your data will be
>>>> accessed. Consider using a clustered index for:
>>>>
>>>> ...
>>>>
>>>> Columns that are frequently accessed by queries involving join or
>>>> GROUP BY clauses; typically these are foreign key columns. An index


>>>> on the column(s) specified in the ORDER BY or GROUP BY clause
>>>> eliminates the need for SQL Server to sort the data because the
>>>> rows are already sorted. This improves query performance.
>>>>

>>> That's all true. To be precise, the bit of your earlier post that
>>> was wrong was this sentence:
>>>
>>> "It should always come back in sorted order unless they specifically
>>> use an Order by clause"
>>>
>>> If you want to be sure the data is returned in a sorted order you
>>> still need ORDER BY.

NumbLock

unread,
May 24, 2006, 5:46:34 PM5/24/06
to
Very good. I thought I remembered a topic on this subject while
studying for my MCP in SS2K administration.


IN the book SQL Server 2000 administration (sybex) by Rick Sawtell,
lance mortensen, and Joseph Jorden it states on page 493 under the topic
"Proper Indexing"

"If you want sql server queries to run as fast as possible, you must
create proper indexes. But to choose an index you must know what type
of queries you will be executing. There are four primary types:"
...
...
"Searches that return sorted data. If you are constantly using the
order by clause of a select statement, then the column is a good
candidate for a clustered index because the clustered index will sort
the data automatically."

In the microsoft press book "Microsoft SQL Server 2000 Database design
and implementation (exam 70-229) it states on page 385 when talking
about when to use a clustered index:

"The following query types seperately or in combination benefit from
indexes."
...
...
"Range Queries. Queries that search for a sequence of values:

Select contactname, customerid from customers where customerid between
'b%' and 'c%'.

Clustered indexes are an excellent choice for this type of query because
the index pages are *physically sorted in sequential* order. Therefore
once the first record is located, it is likely that the other records in
the range will be adjacent or at least nearby.

so lance mortensen, Rick Sawtell, Joseph Jorden, and ms press all say
***YOU ARE WRONG***

You are a self professed Expert who's advantage over everyone else is
fragile at best.

BTW I do have Kalen's book Inside SQL server 2000 which I used and
referred to alot while studying for my MCP.

NumbLock

unread,
May 24, 2006, 5:48:23 PM5/24/06
to
Well, go on... What did Mr. Kollar say?

NumbLock

unread,
May 24, 2006, 5:52:22 PM5/24/06
to
I agree with what you said. The sorted results are a byproduct of the
clustered index. What I said is if you use a query on a column (a range
query) and you have applied common sense indexing rules (i.e. made the
clustered index on the column you wish to query on) it will come back
sorted. Aggregates and other indexes can have a bearing on it depending
on the query. My simple fact. If the index is optimized for the query
you are using it on, it will come back ordered.

NumbLock

unread,
May 24, 2006, 6:01:00 PM5/24/06
to
Kalen, please read my last post where I quote my study materials for my
SQL server MCP. The three gentlemen who wrote the book for sybex are
experts, too. I do not claim to be an expert.

You are amazing, though. I do have a motorcycle and I do not wear a
helmet. But it is because if I have a wreck, I want to be killed. I do
not want to sit around with a mangled body and a perfectly good cranium.

Kalen Delaney

unread,
May 24, 2006, 6:01:55 PM5/24/06
to
> so lance mortensen, Rick Sawtell, Joseph Jorden, and ms press all say
> ***YOU ARE WRONG***

Like Microsoft itself, MS Press is not a person. There are a lot of people
writing for MS Press, myself included, and I say that they are wrong. Why
don't you quote from my book?

(I keep telling myself this will be my last post in thread, because it
really doesn't matter to me if you go through the rest of your SQL life with
this misunderstanding, but somehow, I can't help myself. :-) )

Is the issue about the usefulness of clustered indexes in many situations,
or is the issue about whether clustered index leaf level pages are stored
physically contiguous.
I will not argue the first point. They are useful in many situations. They
just don't always guarantee sorted results.

The second issue is really easy to prove. Just look at my SQL Server
Magazine articles on fillfactor. I show you how you can insert into a full
page in a table with a clustered index, and then see what page numbers are
used for the table after the page has to split. The pages are not
contiguous.

What if I can get Rick Sawtell you respond to this thread and say his
statement was not true? But why would you believe Rick's book and not mine?
I do a lot more work at the lower levels of storage than Rick does.

--
HTH
Kalen Delaney, SQL Server MVP
www.solidqualitylearning.com

"NumbLock" <pcg...@yahoo.com> wrote in message

news:uPb9cs3f...@TK2MSFTNGP04.phx.gbl...

Kalen Delaney

unread,
May 24, 2006, 6:04:36 PM5/24/06
to
See my reply to that post. They are not as expert in the low level storage
as I am, and if you ask them, they will admit that.

--
HTH
Kalen Delaney, SQL Server MVP
www.solidqualitylearning.com


"NumbLock" <pcg...@yahoo.com> wrote in message

news:%23642g03...@TK2MSFTNGP02.phx.gbl...

Roy Harvey

unread,
May 24, 2006, 6:08:13 PM5/24/06
to
For what it is worth, I confirmed your out-of-order example on 2000
and 2005. So, my mileage did NOT vary.

Roy


On Wed, 24 May 2006 18:03:31 +0100, "David Portas"
<REMOVE_BEFORE_R...@acm.org> wrote:

>"NumbLock" <pcg...@yahoo.com> wrote in message

>news:e1Q99K1f...@TK2MSFTNGP02.phx.gbl...
>> That is exactly what I am saying. Read my BOL excerpts. To verify:
>>
>> Create a table with say a date column. Put a clustered index on that
>> column. Do a query on the column for a range of dates. IT will *ALWAYS*
>> come back ordered.
>>
>
>Not even with dates (YMMV).
>
>CREATE TABLE T1 (x DATETIME PRIMARY KEY CLUSTERED, z CHAR(1) UNIQUE);
>INSERT INTO T1 VALUES ('20050101','C');
>INSERT INTO T1 VALUES ('20050102','B');
>INSERT INTO T1 VALUES ('20050103','A');
>
>SELECT x FROM T1;
>
>x
>------------------------------------------------------
>2005-01-03 00:00:00.000
>2005-01-02 00:00:00.000
>2005-01-01 00:00:00.000
>
>(3 row(s) affected)

David Portas

unread,
May 24, 2006, 6:10:37 PM5/24/06
to

Actually I would never claim to be an expert on engine-level details. I
know some stuff but I'm not nearly at the same level as Kalen and Itzik
so don't just take my word for it.

The comments you quoted are wrong if you interpret them literally and
in isolation. However, "physical sort" might perhaps be used loosely
(and rather carelessly IMO) to refer to the ordering of pages in the
IAM. More reasonably, it might refer to the state of the clustered
index assuming the data file is contiguous immediately after the index
is created. Maybe this is clarified elsewhere in the books you
mentioned. There's always a risk that statements may mislead if taken
out of context.

Common sense should tell you that a clustered index that was literally
ordered on disk wouldn't be feasible. If that were so then inserting a
row at the top of a 1 terabyte clustered index would require the entire
table to be rewritten! - and that demonstrably does not happen.

Kalen Delaney

unread,
May 24, 2006, 6:09:39 PM5/24/06
to
Ok, I just reread this. Rick Sawtell, lance mortensen, and Joseph Jorden do
not say the clustered index sorts the data physically. They just say it
sorts the data. We have all admitted as much. The index sorts the data
logically, so SQL Server can follow pointers from one page to the next, but
if you look at the output from DBCC IND, which shows all the pages that
belong to a table, and which page is previous and which page is next, you
will see the pages are frequently not in order.

--
HTH
Kalen Delaney, SQL Server MVP
www.solidqualitylearning.com

"NumbLock" <pcg...@yahoo.com> wrote in message

news:uPb9cs3f...@TK2MSFTNGP04.phx.gbl...

NumbLock

unread,
May 24, 2006, 6:19:56 PM5/24/06
to
I believe that what you say about future behavior of a clustered indexed
column can change. I agree with that although I do doubt it. My last
post was just to illustrate as you said that this is obviously a subject
that has not been fully addressed by Microsoft in their documentation.
I am going on past experience when I say what I said. I am not 100
years old and don't know all but when I hear all of these supposed
experts who purport to know so much chiding me on a fact that is
published and believed by other supposed *experts* and the proofing
staff at sybex and ms press to be correct, I have an obligation to
explain my point. Have you considered that your book might be wrong?
And a clustered index scan will produce ordered results based on the
index?

A further quote from Sawtell's book:
Clustered indexes are a lot like a dictionary. They change the physical
structure of the data to match the constraints of the index. That means
that if you index on last name, for example Adams would be placed
physically in front of Barnes in the data file.

I don't see why they would change this behavior when physically ordering
the data is the main purpose of the index. You might be right about the
data getting out of order in some instances. But this goes against the
facts I've stated. You've done the research.

But I leave it at that. I do respect your work. But I know that nobody
is perfect, not me or you or ms press and if I am wrong, I am wrong.

Kalen Delaney

unread,
May 24, 2006, 6:32:51 PM5/24/06
to
> Have you considered that your book might be wrong? And a clustered index
> scan will produce ordered results based on the index?

As I have said, many times a clustered scan will produce ordered results
based on the index. But it is not guaranteed. The optimizer can
theoretically choose not to follow the pointers if you don't say ORDER BY.

The other issue is that the rows and pages are almost never physically
ordered after any inserts or updates have occurred that have incurred
splits. And you can prove it using the commands I have mentioned.

> A further quote from Sawtell's book:
> Clustered indexes are a lot like a dictionary. They change the physical
> structure of the data to match the constraints of the index. That means
> that if you index on last name, for example Adams would be placed
> physically in front of Barnes in the data file.

This is most likely true when you first create the index. But the physical
order is not maintained. Yes, inserting into full pages is expensive, but
not THAT expensive. This you can prove also. Find or create a table with
100s of pages. Create a clustered index with fillfactor = 100 so all your
pages are full.
Now insert into the table a few rows with values at the beginning of the
clustered sequence while you are monitoring statistics (SET STATISTICS IO
ON).
You will see that the number of pages accessed is small, whereas if the
pages had to be maintained in physically sorted sequence, you would see the
number of page access would be just about equal to the number of pages in
the table.


--
HTH
Kalen Delaney, SQL Server MVP
www.solidqualitylearning.com


"NumbLock" <pcg...@yahoo.com> wrote in message

news:%237UFG$3fGHA...@TK2MSFTNGP02.phx.gbl...

NumbLock

unread,
May 24, 2006, 6:40:14 PM5/24/06
to
If indexes are properly tuned and the proper fill factor maintained, the
physical reordering will be done at index creation. There will be
adequate room to add new rows at the appropriate place. If you have
database with a 100% fill factor and you insert a row at the top it will
take a looooooooong time to insert. That I have seen. If it is not
physically reordering the data, what is it doing? It does not really
matter at this point. If it is not physically reordering the data, how
do you explain the use of the word physically in reference to a
clustered index? And why does rick say the following:

Clustered indexes are a lot like a dictionary. They change the physical
structure of the data to match the constraints of the index. That means
that if you index on last name, for example Adams would be placed
physically in front of Barnes in the data file.

Hey if I am wrong, I sure have a good reason to be wrong when experts
write books with such topics.

NumbLock

unread,
May 24, 2006, 6:44:30 PM5/24/06
to
FOr what it is worth, if you used the clustered index on the column
which you are doing a range query on it will come back ordered. I don't
care what your mileage says.

NumbLock

unread,
May 24, 2006, 6:58:35 PM5/24/06
to
First of all, your query does not even run as written. And you totally
missed the point of the discussion. Observe: (btw I shortened this to
1000 rows, but you get the point)

CREATE TABLE TestStuff
(
-- this column is clustered and this is the column queried
ID uniqueidentifier CONSTRAINT UNQ1 UNIQUE CLUSTERED, -- this column

Data INT PRIMARY KEY NONCLUSTERED
)
SET NOCOUNT ON

DECLARE @Ind INT
SET @Ind = 1000

WHILE @Ind > 0
BEGIN
SET @Ind = @Ind - 1

INSERT INTO TestStuff VALUES (newid(), @Ind)
END

select id from teststuff WHERE id
between
'00000000-0000-0000-0000-000000000000'
AND
'ffffffff-ffff-ffff-ffff-ffffffffffff'

drop table teststuff


7EA28187-EB9E-4DDB-B285-001B4FF79679
25F052AB-EEF6-491D-A44A-001E77B52765
7C248FDE-D9E1-46C9-8BBE-0049485B225C
D5D3ABBC-E13C-4385-A464-0063BF1DC5EC
9DA0DAC1-C38D-4954-A833-00C3CCA59C6D
CD651222-289B-48B5-813B-00E06E35D50C
AE881326-69DC-4C88-ACE8-00FC4341F02A
50154809-047A-4144-B2D4-011A5CE50F6B
4EAA9CFE-E6DA-4283-9BBD-018801F5D4E2
CA13B3B1-C664-4414-8950-01908BEE210C
5A77D1DA-5FA9-4C49-8CD7-01A35C1E1202
A601A283-A743-4B6A-8047-01B4535FF066
0464924F-2676-4146-9FF8-01E8FE3245DF
EC2667BA-B87D-46E8-B57B-0209E688F081
B9AEEE15-9E18-4ABD-98B7-0215F22EFC58
E9C11DAD-4B9D-49D5-B5AF-0231A9499C5A
F8357918-BF68-4054-A2C9-026A3CBC9592
9E1D6FDA-C574-4AAB-BCDB-02C00CF07DF6
45F624E8-EC94-4726-A500-038753B179D6
E5AD2432-0C1D-4757-B8D1-03A0D200EFED
AE37523F-357C-44FF-9273-03D860D40299
83ABA440-5687-4EAE-80A3-04142E83D1B3
7E625D9A-720C-4A51-A172-04479B9449A9
D7C6E77C-3EF6-4BD0-85D7-0471329860F8
7E4E2005-A0E8-457B-A72F-04A042CFA33A
04A9E1CF-93A6-4E41-9C31-04EDE75A4B64
9AEF33BB-F752-4E98-A2DF-04FD5D3556F7
10F1C2D2-EBD5-45EB-B162-050626A2D215
4884DF77-F2FA-4097-88E8-0539D1DFEF1C
E1EE72C3-5888-4923-B5DD-055A0F6E3D5A
8DAEC0FE-72C9-4D06-8223-05F2C7CC90A9
7C8C8092-F7FC-437A-ADCE-061D74ECC628
CA062ED6-A07B-4F6B-AF2B-065825728844
8DB2D9B9-5324-4FAA-9F2D-065FCBBAD84A
3A6E6B6E-BE65-4DD3-A91A-066F524D0D50
2DEC6A72-844A-4185-B076-0676E1A1146C
9F5D734D-C28C-4086-BD84-06EF31470EFB
3CD31C0D-CEC4-4AC9-BAA0-06EFC296935B
CD22F070-007B-49E4-B4AB-071E54A5DEFC
7731E034-0623-4C2F-B6AD-074B7421ED79
29C5ECF7-AFA7-4771-9660-074EEAE33009
5FA1D878-C625-4A6F-A33E-07DEACE6E673
940ADEE6-B016-4E40-B995-07E187546155
BE7D3F9A-93E7-4774-AD30-07FFD281B656
3367F6F2-DC1D-41F7-B5CF-0815A73D5109
B9D0E8F7-F2CE-444A-B784-08224505D32C
8CC8CCC9-F476-45F3-978D-085A722F7CCC
1965C431-D745-4397-AB25-08CEA472877F
1EDB77DE-1A06-4E52-9098-0951632497EC
D78D0660-C7AE-4C59-8962-0966F4C11137
91603345-F968-45B1-8D97-0A654CE9A279
32152065-2899-4A49-8F6A-0A8043276951
D81B020E-6187-4ADF-8847-0ABEF99F9A8D
230BD9D8-8CA4-42D7-933E-0AC5747705BF
891733EC-FAF7-4525-8598-0AF19AA03DD6
BFB79B98-89D7-4EEF-8AD0-0B70A1482BE7
91AA3900-D39A-41F4-833F-0B7777D73C87
F79DA3E0-848A-403B-AAA2-0BD7D9DEFD8A
8FCD820D-B4A0-4D0F-99E2-0BF1A6FCF1DC
EFC7B9B0-EA04-4DFB-9CD1-0C473C32120D
8A095236-81DF-4406-B75F-0C92C92262B1
185D155D-B6F8-4A6F-A4B0-0CA9A8D8B4CB
5D4ED52F-F9A9-4CD8-9BED-0CFB34683FAB
46A6E101-21AB-454B-9F2D-0D271C22761F
E3F6AAB5-907F-4A27-BCBB-0D7507696491
692F0A30-B41B-41AC-8948-0DBC82301EA5
B13B579A-36EA-41EC-86EC-0DF2D5AB4883
EC62E37E-030E-4C15-B68B-0E18E658BD07
89D5C997-8E54-4BDE-8746-0E42FCA13AE5
D2E7A57C-4D0E-40FA-81D6-0E48385F8516
4AAFF81E-F691-4918-8D69-0E4E13B2BD13
58CB35D7-68BE-42DC-ACBD-0E553F7C3F0D
721F9F74-C351-4D2C-9AAC-0E98B2F83373
707A1691-A40D-46E9-BB92-0F42D40590C2
B0D8F10A-0D90-41A7-AEA5-0F4E74ACE618
8939BE30-95CF-4CC2-A946-0F79E422E329
63AF1B9C-0AB8-4507-9FF1-0F8E88A20168
2C71E475-0F90-462F-B9D2-1042842BFC68
064CDF9E-2DE1-4C8E-81B0-10B931EFA858
495D60DF-EDED-414B-B432-10C641FB9F3C
1E67603E-042D-4CF9-9D59-11E83D5E4AE3
D7F5CB54-BE3A-45C9-B59E-11FED210058C
61F6F918-0429-45EE-97E8-12127CCC5F55
185BB83F-D1C9-449C-B710-121CE652A85A
EC3B8518-21CB-4E0C-98B7-122029FD7FF7
FDD0FC56-5E9D-4949-8B04-122AD337CA47
DF9686CD-60BB-41A5-9FBB-1254EDFB7CDC
F90DDFC7-2FB0-4BF8-ABA1-130B0E401481
2770959E-847F-4179-9888-1336C76332B9
DC9B3996-3A3B-48FC-B2DF-13422E6F1DBA
93096885-86EB-4A17-9928-142CCE865120
F1630CAE-65E2-4C59-9BF7-1445DA84D6B3
8DA64567-9257-485D-B322-1491AAF71E80
A5D99D63-77F5-4BBB-A0A4-14B1EC24E3A3
851FF2B9-5D36-4634-B21D-14B62F25FF4E
8232EC3E-0484-47AA-AA65-14C76C321FCB
78CDDFF6-9594-45AE-8FA5-14F11F6EF753
CCB30866-50B3-4671-97D1-153A9150E113
FC2B3B22-80A7-4FBD-93C5-154DFBA383E6
F387CB43-F00A-4C33-84E2-1591E0554EFD
43A25A17-BDAB-447B-84EB-159A29150107
299DA654-80A4-402A-A1A5-15AE8D8560BF
282FE6C6-1FC3-46BE-81CB-160B66783CB5
648104EB-56FF-45CB-872D-161FD8AE416D
F84E7391-E6F8-490F-9A80-1633F7635CF1
88BE92B1-5989-4F6E-9808-165E243D70E1
1BA375E3-06B3-4517-9258-166480B4C259
F836EC8C-F8FF-4BA8-92AA-1694B1F43DD6
7ECA78B2-7641-4869-B91D-16B486CB7679
07F0AD09-F877-420A-BB75-16C6A75933AB
E6EDFD91-5884-4821-975A-1723DBFB9615
FEE8934F-4BFD-48E5-9C02-1729DC0C92D1
B9F92EC3-7280-4F39-B0D6-1778445E8471
B245CC96-125C-4EF3-81D8-17A13ADDA187
31AE491E-7681-4EB9-AFA5-18193EF9C68E
CA097462-96A8-419D-8528-1833833D16AF
1E9AEBC0-8562-47EB-BD33-18500E3ACC93
772B0621-48A8-42C7-AFEB-187AC7BA8F52
403938C4-ECFD-4FDD-8C3C-18D7DB0AC51F
BB780C8E-EC7E-4432-AAF4-1963D49A66B5
4903BDF4-7526-4F9E-B695-19917B088E97
9321F599-6EEB-41B0-90D0-19B510F429B1
F8898FC6-4F07-4109-84BD-19D2E5D804D0
820D0A8B-75AA-4CAF-BDCA-19E0E58B2498
5470F0AE-594D-4DD1-92F9-1A726658A945
BCB18940-19C7-478D-8ABE-1AEA5A2408A8
721DD063-5D9D-403E-9396-1B54909BF595
B89313D8-5319-438F-8DBC-1BB2B8EDE059
DC240E12-C7F9-45C8-AB0F-1BE875C0E3F8
35443892-4DCC-4BB9-A951-1C847C9194BA
96E92DDC-125D-4E5E-ABD6-1D80FB72C26C
05FE3DB0-D282-403B-A0F1-1DC3988A12CB
42F0FA09-213A-45FE-BA22-1E26FF7434C1
447E4BD2-3B89-4030-BDD4-1EC27DB9817B
D241C029-A573-48AA-B64B-1EC3A34F11A6
1DF08847-B734-4D6E-91F8-1EC5C42C7E58
9E1664C1-DD69-4F3C-AB9C-1EF1BB304D55
0B1C97A2-0C16-49EB-922C-1EFE203D1B0C
60BA35D5-5749-40D8-8943-1F07367AAE2C
9F395382-4A85-44B8-8473-1F09D2621EBD
9F3181EA-04BD-4067-8BC4-1F58FC8FA664
830360E9-A720-411D-9134-1FA85B5C22C9
38A9C0C9-D2F0-4209-AD3A-205582728BEA
956E4A82-B817-4DA4-97B1-207E563EDF41
5F1350F2-C8AE-400A-B026-208DD1A45EC4
920AEC82-15CA-43E0-984A-20AD0EEBB39D
0433CF2C-8A11-453C-A895-20DB3D486A88
3078A367-2863-4A72-828A-20E6A0D8E976
DCF5276B-9472-43EC-8833-20F30D57D42B
A9467A1F-01B1-4D81-AD84-21237A5879AB
F3F7A312-F597-489B-B8F4-21490D2F64AC
EBA6795A-3526-4040-AA5F-214F3E4594FE
C5647D4A-80D7-49DF-A721-2176102B3FFE
9665C76D-013B-42F2-8B0D-227E8674FE52
0960FE21-8C57-40C7-9298-22A2F40EB726
18AAAEBE-31B5-4974-9466-22BD00CD6F71
8EC0F928-E977-47C9-B9EB-22FAFF43C138
D028889E-255B-4C53-B0EB-22FB0019B61C
AD6C9F4B-E484-4ED9-ABEC-233F533BD84D
62E09C82-615A-4A71-9551-235236388860
BC551B69-E42A-48B8-B485-2430EDBF5D57
FCCBF800-02F2-4D50-841F-24A87544BDC8
ADE58D93-AE4C-4D70-BBDC-252AF8ED7796
07CB1B13-8D98-4018-BE53-253BC25395B4
B41A33F1-FBBD-43ED-BBEE-256754B79367
7A819ADF-E418-494A-AA8C-25C6E870C006
D493B5FC-E2F6-45B1-AC29-26349F910729
6BB043DE-9F51-4CFE-BA9D-263519CEAFC8
6234561E-CF16-4604-9DEA-267F4F4B162A
E95730A1-A716-4F88-B920-27093C211AD0
EE6DAA5B-C458-4E35-9F73-2714E2BCFD43
B0D23BC6-D7F0-4C5C-B185-282C9FE77719
12C35C36-4A17-4528-967A-2866BE57BD4A
6FCF4176-E5F1-40D3-ADE1-28942CF7C983
2079BEB8-BCB8-414C-A504-28ADDCF22BCF
D695A90D-9174-4194-BA30-28AE0B79663A
A1A1AE18-23EC-42BA-8015-28B565EE3DE6
AE3216E5-9F5B-4E9F-BBB2-2917390F4ADA
745719CF-D6E1-475F-BF2B-29810AE0AE7E
A89D6991-9AAB-43E2-A56A-2992F82AB1AD
DD6F5CE9-9191-43A2-96EB-29A171E953D0
960E2AB4-060B-40FB-8F9B-2A7E39972A88
7BD19111-933C-49A4-A186-2B12061AA28A
0EC72753-C5DF-47CE-8325-2B1894AB4388
0BBFC4A9-70DC-4643-AAEC-2B287DC87504
3C524E41-C197-415D-BC85-2BD1B13F6FAF
B2239376-8030-46D4-8362-2C30C1E886BB
BAD78826-0A8F-49BC-B951-2C37CFC756E8
93319189-4987-41D1-A379-2C3A5C7C4925
D64BAEE6-29B8-4B20-A8BC-2C57E6E453C8
70922710-A8F6-4BA9-ABF2-2C59168DA3B4
DD3541D0-0949-49A9-A30C-2CCB73DABF13
CBA9AE50-0733-4101-A641-2CE4CA574A88
D79DE65C-E3D9-44F1-8CD0-2D18C62BFB6B
BD480CE6-8254-4F30-9700-2D2338BCDD2C
F0775BBD-015C-460F-88ED-2D43C204FB75
A19683FF-86EC-45AE-A532-2D5A5F00D076
5B5AC302-FD90-438C-B722-2DF017DA46E9
7C7B81C9-DD52-4D64-ACC1-2E047A54E3CE
EAD1263F-E92C-4A53-A0D8-2F5FDFFA4F8A
7652A86F-8854-4DBB-9C3A-2F62F593AC39
36620E1A-6E0D-4D95-93BF-2F7077949004
BA3A0356-F5E6-47FA-94DB-2F86B32E18E7
B5002A1B-A088-470F-9DC0-305DBC1A3C09
44940CBD-674E-4FB1-8F3D-30A5848ADF53
07D454D5-9B97-4E7E-8FFB-310F011F3C7C
02150D75-7FD2-44FF-9430-3130F7B53DA6
6DCDD09B-8029-4231-BB88-318FDFB76911
2B8919EC-6DC0-443C-BD6E-319883A9A4A5
7FFCD08C-DAFA-4061-A9D3-31A58AB56D37
5BA76236-9898-4993-A623-31B109AD3F50
20EEA601-C856-47FC-A524-31C3A1456414
83E9E4BC-D1C6-46A8-88DD-31E5B883A1F9
64606AF3-0B07-4409-A629-31F9CAF004BF
BCE035D6-8E8B-41C7-9E5B-322A0A452807
E1DAD6C2-2202-44A1-8378-322FD6B31184
06102072-3505-4A5E-A45D-32F8740AAF92
28BB0BCA-AAFE-4D51-A6A3-33108189D21A
7E543C76-238B-485F-9806-331A73D9DFA7
846421EE-C424-4951-86FF-332640EA2236
4A583A85-CF14-4CEF-84A0-335B23F8C9D3
561C6E59-E55A-4A6A-A2BA-33BF8D2A3E6C
7104528C-F352-4434-AD09-33CE16043D45
2197F3A7-E3AF-4309-AC5B-340648F3BD7C
E5A12E6A-9073-4D42-AC5D-34309FE4B40D
A65184EC-0920-4475-A1C0-34A7C0EE28B6
FEB38256-2F5C-4E22-80CF-34C3728EB384
45B1AD23-DC8B-4D53-829F-34D10C43D915
F7B572E9-8048-4F98-BFB3-34D3D1DABE9A
EB995A3A-4FD7-4E79-9296-351A17B5D3AC
017458A9-DA1D-4E27-98D1-352C3BC0D834
EA1BC3D4-D9C3-4AF3-96F2-353BDA3D0547
A6BE42F6-3577-4CEF-A972-354C96105F0F
29C12A73-DD8B-4E68-B3DB-355D8ECA7141
57BDD540-6EDE-4EC9-8A56-356FE6C0FFD9
99046C9A-FCA2-4433-86A9-35EDDA014290
6A701E27-5E3B-4A85-9680-3609547ACDDD
2C7BF050-465E-436F-9F38-3614E1B1B9CB
B7D39A7B-7943-44B0-8A01-362FBE05A71A
77F84A94-167C-43CE-94C6-3640CA1F0079
5B0141AA-1E62-450B-BC28-3684FD2F0CC0
854FCA68-65B0-4BDA-93FA-37273CE3C65F
872CF301-7DB2-494F-868B-37D4F0B9CE49
1DC93468-C2B9-4F28-A2FA-37EC40ABAFDC
A110119B-E541-49FF-8CDE-380604103DDF
3757B603-5729-429F-A9E2-3848F182B296
A4EC614D-EA23-44C8-849B-38CDF453310C
74A0255B-27A2-4F6A-B820-38E4CF0DB73F
FD82EC25-9A7D-4543-A488-39213E283B39
9643E5F3-08D7-4D8B-9FB2-392B41E7892B
1F49F4FA-3A66-4A07-AB47-392E25EF63E9
3B185E67-C552-427D-B4D3-3955055FB9C3
E2904E2A-0756-4726-AC81-3956B869FB96
DF290F1A-A1F6-4945-BD6C-39B08705F32C
80CC26C1-C3AC-4C0C-BA5F-39D5A32DE0E8
3D032FED-56BE-4EDC-A4D7-39F14D033C33
DDCE55B3-3FAE-4B7D-B86E-3A06CDE756EC
72652A28-E5AA-4362-BEEC-3A1FAD1B3247
3ACB3C1C-F690-4A4B-BD18-3A39D838952C
0FC61B3A-1F52-4420-AE44-3A4FCA14CB90
68CF0360-BCF6-440E-A685-3A7A87AD681E
6EED210F-3A41-4969-AAE3-3A93C7556D68
EB446D0D-1141-4FC7-AE94-3A93ED33F0FA
74DEF591-78E4-4F48-B002-3AB7928C1710
0B5EFDF0-5179-4D09-99D9-3AE3B025C8C8
584CEBB1-840C-42BC-AC8B-3B018F1D57D4
EF33CFE2-642A-48BD-9600-3B14B2EA68CE
76CBCB56-F23A-414F-AADC-3B59F44115E4
93BB885E-0320-4621-8D67-3B7686477935
352B7DE2-166D-4360-8AF7-3C698D27DDC8
6B1FCD6F-FF79-4DBB-900E-3C77EC9C231A
BF127C47-F743-446E-8C09-3C79815EB2ED
42672D30-C7F7-49B1-9616-3CF1242476F8
7BDCCB93-E88C-4E36-9FEA-3D217B9E0C21
185EE580-81BD-44EA-921A-3D49F55FC948
C9806B0B-6BB5-4933-B474-3DDEC1736BC3
3067C037-2480-4ABF-A4E8-3E00877684E5
01039481-D690-4697-9012-3E02B73E8368
B01489F3-A723-4AB2-9CDA-3E925271C9B7
98A1DDA5-7716-4677-9FB7-3ED02BDC8401
C81D634C-7400-4DCE-A5CE-3EEB92B59FF7
E7652C71-B46C-41D9-B343-3F01D728C736
512A4DD9-EDC8-4C5A-9C51-3F0E558035D5
C804DD33-1CE7-433C-B6D3-3F9110B18A69
50FCE5B0-2D73-4DBB-96B6-3FC074B78E2D
64746E21-F0C3-40F5-AC7F-4000AB2D383B
C192E1A3-545D-46B5-8A6F-40055D0D1DE3
134FEFDB-78D9-4AD2-8EDA-402BAD1B254F
A4985BDC-6288-4489-9DBC-40E5EDE1312A
F705648D-673B-4FC0-AAA1-40FA5562A087
E0CFD034-9CE2-4548-BDB4-41855A453254
76EA18B2-0FEF-4A78-94D8-41BE9C31D529
42A75763-7689-41BD-966A-41D0C67408C3
27E9585B-7525-49D8-9351-424083FC6F46
9DFA639B-C192-4AD7-91BE-424156FB808C
6B2DF2D7-6E5D-4A71-9B31-4271584B95A7
321BA3D4-2425-4E17-92DF-42BA0B24BAC3
218C0E64-1C9E-4DF6-9966-42DCF20B2448
66AA9F62-E9A7-4C66-A992-43331FD814A7
77459453-E587-41BF-BEC3-43944D1DF5A2
0A628927-57E3-4A45-89C5-43E47F5B73D5
7DFBB6F8-C6AC-4F4C-ACDF-4436E8954DCE
FB6882ED-DE3B-4355-8FC0-443D81C2CDBA
B3850056-E147-46DB-B3C3-44669FD0173F
7478C291-54A1-48C8-BE40-446F1A352DAB
735DFDE8-4604-4627-9499-44887427652A
81CB9C43-E26A-47A2-919C-44A1EFF2F5F6
2C06D5F2-57A3-4406-8024-450FDCBA8ED1
F7701AC1-A9A2-4472-8CD2-456E6FC14730
5E100215-577F-4CE7-9DFA-458C6D811914
F9C23127-CABD-4233-ABE2-4616D41FE351
8DE64217-0F08-4D4A-9405-462219643E71
3694FCA7-1D3C-4A2E-9EA9-4639CCD0D528
5D2C9823-099C-4DD3-A391-4787D2313B5A
DFBE62DB-318F-40E9-81C2-480B70B45397
9A59F559-A6CD-46F7-8F5C-488539BDE3AA
F2E4EB74-D0F2-4F1B-A23F-48B16DC21D79
EEF53D18-F446-4E7C-B026-495D818B1E70
BF504282-EE70-47A0-8390-49811D39B8A4
4B33F85A-8657-4A97-A579-4A0C6A4E25BF
A15B9C37-E8D3-43D8-A815-4B088907419F
CE365AD7-03B4-4FE9-94C8-4B5E9F625494
C6997D4C-09FF-465C-9376-4B6B4F0E7AC8
DF01056E-1FE2-42EE-9506-4B6BC9642F52
5FDB796D-925F-4FA1-943C-4BDD288F4E64
FEAA4E8E-5CA3-42CA-9869-4C040EB391FD
43AE6CE9-1C3D-4188-9929-4C2600904D66
2F88CC06-3477-403B-BC2E-4C9319AB4967
9A6F0FDC-E0A0-4385-8E25-4CC91BDD31DA
65AFBC3F-7214-43F8-988F-4CD80F954272
CBEA4014-F5E2-4309-9DB2-4D863F3EC3E7
DAB91C35-3760-4615-A2AF-4D8EEF3BA6A6
580653A6-9172-44DC-8FC0-4DC87B0B525E
FB88422B-984A-451A-9F7B-4E1065A9FE92
59161316-C24D-428F-BABC-4E18B6DABF95
98411BBE-B33F-4FE8-A1F0-4ECB5E14D2FA
DE134917-1E01-47AD-B940-4EF9B2290E52
DBF96FE5-3E29-4800-A90A-4F467899DFF2
CB609755-4ABC-4F16-9540-4F56AEAB1C3D
22B0A0DB-F23C-40F5-87C8-4F8227C84F2C
403C70AE-F48B-4B5E-B464-4F9AA0155F16
7469EAEE-BCE6-449B-97E9-4FF45E3847ED
3B6F842B-CCA7-48B0-9B88-4FF6B1A93BC3
052EE33D-1E0A-49A4-972B-507231840E84
33A19008-90A3-4B12-8204-5099BFEF156B
3E5847C0-F947-4C13-9541-50AF233B9AFD
28AC2FEA-4E68-46F1-94A0-50BE30E16927
D95D3E47-1CC0-4ED8-A489-50EA0AB016D9
10D83DFF-C215-40BA-9172-50F5B1AD120D
CB2DFE6B-22C1-4BE2-8766-5170CBD8C0A3
8904C8CB-2263-4BE6-A035-51AD7F33FC11
F9C222EC-0308-45CB-A925-51AF25E39417
CA46B21E-7A69-47E5-98AF-51D7BCA5E036
A71DA99D-0F3D-40E0-89F3-51F7ECFFC4E7
32E83FA9-493B-4FD7-B7E3-520F1C77B71A
6664D384-8D0B-4EAD-B14E-526C9D01CA24
2AAAA0E7-5306-4C7A-B5C0-526CB3722CDB
43959065-1FC4-48C6-912E-528F99029788
63512C0E-3EEF-4B67-8E1C-530A421BEBCA
EBC73CDC-C287-4E51-9009-534F9E084862
C03976D2-8E5F-4BB2-A31B-5366852870DF
6841E43B-F05C-44AD-A308-536FA6024984
77DA032B-F1C4-4AEA-8B60-537C8BCB6DBC
9C453B56-6EB2-48DD-B3BF-53A9274C8D6B
B36E560E-5954-429B-92AD-53CA57E5EF1E
1F1892E7-1330-4827-8823-53CD79CA2316
AFAE0A6F-42EA-4CE4-B251-53D37EEBE70E
D43EE64C-EB0D-44C1-B78E-5465F778EF75
1D151658-6AF6-4DCF-8455-546FA4998E71
EDF44240-9F93-4455-A04C-5482B0EC1157
9912217E-0CED-4905-AA38-5530E526D193
ECFC770F-A904-4174-8170-55C3003B2784
AC20EF2A-E5D5-45BC-9A77-56BD006B58EB
EE83FA47-7D11-4C2A-8484-576E5F2E11F3
E6F18554-7C11-4D92-9BC9-57AFB2673E3E
07ACB1F4-8395-473C-8970-57E0F8991FE4
249E59F9-978E-456B-AEC4-58684C2FA2CF
F4C67862-AE12-4345-9900-58A01F5667B7
20869E4C-4BC8-420E-8623-58AB63944C0B
09F1DB63-A899-4E55-8BE2-593E8EFB78C2
ECED4341-E90A-4491-B832-594AA87952FB
E593D5D8-FE3A-4BAA-B9BD-596FE0884C2F
F4CBEB7D-4DAF-4BC0-AF6B-598F67B5D41B
60967AF5-AA2A-42DC-BC80-59C4AC32BDF2
C8AE7870-328C-47BC-9005-5A1EDDB92EA1
3F326834-B29B-4736-AF9E-5A37A7D76F92
39D085D3-62D5-4ED3-9E7C-5A6E075F0FDC
B58EE736-20DA-476B-A1EE-5AA6D18F9E22
8E07E6B4-0B7F-40FE-812F-5ABE806003B4
BA4759E2-2F98-47E6-B764-5AEB796D4A87
CD2030A7-BAC9-4317-A257-5B6200FB1FE5
CDD8F5E5-F30A-42EC-A59F-5B6A0B35F4F8
63B945AF-FAA9-477D-8558-5BD3A9CE92DD
1CECEA8F-090F-40B0-8984-5BF47DC6F3C3
23D74968-AA2F-410E-B35A-5C1507EF6C01
EA6FAAD4-882B-4913-AFF7-5C2C2E407071
1E693760-445D-45DE-9280-5CAEAA5D49F1
3C352351-4662-4A26-98FB-5CB6D41625C4
E3D61190-B5DF-4813-B51E-5CD1443A16F7
F73ADB25-F745-4A5F-B943-5D1175E89C46
04B6B1AD-159D-4E5A-B39D-5DAABD353DF3
9BBBF103-6BFD-40C9-9FDE-5DAAF700DCA1
31B4459B-802D-4C1C-B8BA-5DBDF4D94237
58CCE999-66E1-423E-888B-5E6A9FCF4108
1BC28AB2-78FC-4A59-BA46-5EBADFD84E92
A05E6902-21AC-4C01-9520-5F0C7F698C79
52C70B34-BB35-44D9-9E70-5F161AFF28E0
4B91039A-67E3-45E0-9C2C-5F1B4007D6F5
229EA7A3-428B-4003-839A-5F8224AFA100
968B4F3E-308A-45AD-AF06-5FEEE165807E
FA222DB0-5DAA-4D76-8EBC-60281684C4EA
93188D5D-4C69-4BD9-BBFA-602D33DAC276
FBEB0781-35EB-4C28-8407-602FB5CBC235
405946EC-3AB2-4F30-A849-60569628DDBF
BE7E214B-BE1F-4A97-BB18-605DC35DAAAC
D5E4E98B-1B5A-481A-A9F3-6094AF96B455
6C447019-316C-4FFB-8E33-609F2C279A7E
B15E7298-3909-4EF3-BD28-613B05B4A7B9
5D56D79A-984E-4AC1-8140-622869F3B2F6
24C7108C-160A-40F5-AC3E-6240BF89B2E2
DBBFF8A8-ED92-4025-ACAA-62497E9A10EA
7E04DEBD-4E74-4E46-8EFD-6258E18BE18A
30242A26-C011-43B0-96F8-62B38327FD4B
7098A08D-852F-4B70-9478-62B6294C0E1F
291ACE96-DABD-42A8-B257-62FD9777FDD9
A1AF1D80-8C0B-4C96-B9FA-630D4CD20863
1D717A4E-2F97-4EF8-9AD8-63FF1A4AE9C3
0F011B48-1972-4981-9026-64079792F797
8B13357E-59D7-47D6-BD25-644E3E771F19
2C3CF19F-CBEC-4428-A8EA-64DB6878A5CF
7CF79955-023B-4897-86B6-64E8CD562764
D3D1F272-819E-4596-A90F-6540B69C8480
440725CF-5CD8-4764-B6B5-6565C0A0F899
68BE0F5B-91DE-4D09-8C93-65A116C6A30A
78806956-6970-43E4-808C-65B710B41FC8
70CB103B-6024-4174-A788-66473BAFC3A6
C20CB1E5-170B-4118-B6A4-66606C8FD3E6
881E2A31-2A21-41AC-B20E-666C94C9F432
E5888B63-2392-44E3-AE13-6688729F45C3
4FA1453F-0AB1-4731-9396-66B0A6CE4A19
3C631BBA-E4F7-498B-8E22-66CBCACEE74D
559F963A-936B-4610-A518-66CF619B1040
C0850333-F143-46B3-AC02-66DEA4653827
659F3FD8-A273-4B43-ABF3-670E1AB09F63
3AC66E16-65B1-4B88-A9D8-6721F0A14105
A8CE5A4A-936D-4B51-8126-672A9F6E5C5C
E67A1E39-10FE-4613-A8C3-67754E920738
7F2B1756-3351-470C-8262-680FEB51150E
EA05083E-DE34-4BF5-BF79-685D499630A6
4213B067-45B2-4933-BBCA-686D547CE22B
626CD1BC-50A9-481E-B0D0-686EBF2E09CA
FA16C69D-64F4-4657-954C-68B46FD4E481
A4CF5ECB-41B8-4FE2-B02A-68E6DE65BA3B
C347B631-A391-4468-8747-69D522AC1674
10A3C874-D019-4EBB-A398-6A0217769EBA
0E82734D-65EC-409A-81B7-6A309C536C8D
AABA11CA-C769-4BE1-B6A9-6AA44FD35460
0E083910-69AD-46C8-B85A-6AC7EAA1EF69
AAEBF123-033E-4A46-A4ED-6AD33F62E888
C50688C8-CABF-47FA-B68E-6BAA0F6B6FDF
0ADE8FE4-0A07-4A3A-9E3A-6BBE2D4DECDC
52B6F159-3C3E-4AAF-B389-6BCFF366C2A0
B63A56E7-5E05-45CE-BD78-6BDB20E17276
980284C2-31BF-4743-8675-6BDDE86ED0E3
E5A47859-3601-420E-8BEA-6C06C13395BB
F35A3284-5AEC-4ABC-AC88-6C73FA92EE6B
0FE9406F-8AC2-42EE-A9A5-6C7F54205519
76F3EB10-9B1A-4039-97AC-6C98DE4E0F30
2C0DB19C-2DD7-4FFA-AC62-6CA24488274D
C1595202-DB84-493C-A6AE-6D4F9C7C82A5
2C2100D5-549A-4918-9CC5-6DA98C1F69A1
6EF87330-5F59-44EF-BB68-6DEF6F4F5A16
CC2FCE90-8BB0-4411-A6E6-6E10908689AB
47BAC496-B233-43BC-9E73-6EABC96E3507
6638C6FC-BEC9-4F7A-A7B5-6ED277F65B7E
372CF3A6-F8A8-4BA1-B541-6F762FD83D39
A555608E-ADEE-4C50-B8BC-6F7826FFAF36
9AD95827-DC2B-43CA-8D24-6F9C63B5BCB4
E3F03029-0861-4226-82C9-6FABAD147A2E
EF25604A-5A0B-480E-A1E7-6FC2F312E23D
A1A2384E-45D2-4E5A-B7A7-6FD47E6779E5
82DD3A62-403F-43BD-9635-701834CE6558
5E2D8CBF-6AC6-4C94-A62A-701D16CB15AB
698894C8-69F3-4744-8AFB-707FDF9B282E
7CC386CD-C0AF-477F-AB87-70AC53B1EE1C
4EAB5068-E975-4A00-BCFC-70DB14ACBC0A
52A1C20E-BAD1-4569-B530-7122E62D4C0F
24DBF3D3-6BDA-485A-AE7D-712CF807C3C2
35E41467-A3F0-4183-A75D-716BE9FFCD62
7EFCEFB0-F5C1-49BB-AD0C-71899BD33B05
0A63A2A1-5EF7-4308-BB1D-71965B1E6A87
5639D82E-D116-4A49-B8D6-71C777116EC0
B89AEBCF-61F6-4A57-BF20-71CF22E4508B
5C45F685-2282-49B1-B370-71F3D94E3FEE
E0DA2711-E827-4B31-A0FB-720727BDE2EB
D2D1A326-1E0E-4A7B-B8CA-72B9846EB3E5
50E3A963-3F6B-4406-9988-73347D121296
66D5C198-3738-4983-9E66-73C989D9CE84
19EA7681-0F01-4DA6-AEE5-73FD65178E00
49CCC866-ADE1-4AC7-ACBE-746115B04EA1
6E58E05A-7596-4E82-97A1-74B357D26C84
F5B4967C-61F0-4FB8-AC7A-752E5078C939
0304EB86-2AC0-44DA-AA0C-758A941FFFB9
CA6B1C82-BEE9-40A4-8FB6-7599F0F53858
254F22F8-335F-415D-8963-75A2EFEA8568
00B9E06C-CA5E-4157-83E0-763322C5AAA2
9D2B2A90-F9CC-4A68-AD6B-76C47B0C9812
03491073-84A8-4ECA-B063-79A38DDF0F92
B6528AB1-7FC3-45E4-AC1E-7AC30DDF4349
85EDE48F-EC3F-4483-9877-7B2A65682787
56355374-C32A-4428-B302-7B9AF867D283
919C3CB8-F261-4661-A763-7BD43CE364CB
03640EE9-49B4-4922-A9E9-7C03AA78C921
FFBCDACD-E9D4-4369-993F-7C313B61CE7A
02D1DF8C-9BE7-4797-80F7-7C5B9CE59B67
62DC07B5-99F5-48B9-BB4E-7C70F97E0BCB
F4498CBA-048B-4242-AC62-7C8493062A71
C4EAB868-0669-4423-80DC-7CAC48155C78
160A2AD8-0D63-46B2-ABD3-7CC44714EB83
52C314E6-64B2-496B-A7E2-7CCB60CB676F
51BE576A-C2A9-4454-9AFE-7D5705F3309D
51C902FB-E3DC-4CD9-89C6-7D7C630F0190
C4F175F6-C46D-430B-BFA7-7DE63993C253
E1E101E8-894C-4588-B84D-7F00D44F234B
2D7B19AD-662A-4B3C-9F3A-7F06DD933142
F6A5B6D8-9AD5-45AD-9808-7F0D4062ADEC
096351CA-7CF0-4786-8B07-7F15F730E5F8
701DFC9D-A61F-40D1-9484-7F46476C283A
14C1E85E-FB08-4D92-B9B6-7F6B6B808067
EA434B11-F1E5-4FD3-9185-803AD03F13E7
6C73F291-81E1-4D4F-9C99-8057D9222540
F3D61123-2E8E-4122-AFF0-8089F4FEBCB8
D6AC6783-6995-4037-BFC4-80E323A302EC
5FE55FC3-0B97-424B-AAB3-811A1A052602
573E3F93-AB7C-425E-9F52-8129BB7E85C7
E4592606-9AEF-419E-9A57-81459246B72F
0E33F47F-84F9-4D3C-9F08-81DEDEBBB9A8
A6E4EF27-0B45-4E17-A9B0-81DF0B8672AB
1067A0C9-EDCB-45CF-AB1E-82976E2CE4B4
0A57638C-D9C1-4A95-B908-82DE26BA4017
66B160D7-B847-4CB9-923D-82E14D37A893
C97454EE-0E04-490A-BC39-8332F1FE2CCD
ED046BAE-54C3-45BB-AF9B-836317BEEE32
6A534C59-35E1-48DC-9404-848A7037FF02
199D2020-8F4E-4B6E-BB0F-85414BBB6022
8A6A2DD3-CA79-4C21-AAC1-858A2B5D52AA
13555EB3-FA2D-4AFF-9D7A-85AEAC04EA48
5D90086C-6AC8-4DA0-83C8-85AEBA5ADDE5
ABD42555-BD91-4B90-87B5-85B3D75E5FBC
29E8F6B9-8F44-4987-B80E-864EC5141B10
9C0D583C-B1FC-4811-847B-865340909DA7
756DF7D4-F634-44AE-B482-869E78CD45B4
223665E7-421D-4A85-99EB-8725DC25A4A9
65BD94D2-C138-4302-A8E2-8745528DB5F7
274044C6-1D0C-437D-A2B0-8787C5B252D4
8ED4A1A5-3A4A-4B88-84AF-87C2AA6DFEA2
CD20987A-C06F-4746-93B2-883F708CC32B
50DF3326-9022-49C8-B147-885AB5AA3231
52D65C18-4EE9-426B-BBE8-88707803C556
3199D32A-9FD0-49E9-9355-889EF0F8D67D
F8D05CB8-928A-4D23-890A-889F552E072F
FD7F0A06-3650-4CC5-B9C6-88BB0BA578E8
BC073035-EAAF-4B65-8998-88C81DE851AB
B8A71BA6-991B-4EA0-A6EE-88D98518D933
A4D0AAAF-EF3D-46B9-BBB2-8919A2A6A997
3CF06E32-B23F-4673-9533-894F37B8E29A
A4AD9FB0-BE2D-4E0C-9383-8980454CBEA7
0170356F-55D7-40F2-8B3D-8995383C7A3A
3CE870F5-F0DF-4A7F-B702-8A0C3DA8294C
FBCA7200-64D2-43F2-9014-8A933AD1AC34
3D3A230E-D3AB-4895-A315-8AB2D3E28BF8
943BDA58-AA0E-40B6-AD02-8B30999832D2
34992D42-BD8C-447D-856D-8B35A07AFCFA
CE652A0C-B364-470F-8F46-8B35D9662241
3C9C0F99-4556-47FE-A7E0-8B7EBFE625D7
608ACC16-9E3C-4637-8409-8B9098146D08
F5A6E536-A465-4BF3-825A-8BAFE8990BD9
20DCBBD7-82D1-46D6-88BF-8BE503B56754
6D51ADD3-6B89-4600-AFFE-8C9F0C91AEF1
B6D3AB09-19FD-4873-8143-8C9FE3B1E01D
A15C2CAE-54F1-4E30-A43D-8CB80AFB1D1F
C78180E2-2D4B-47F8-A233-8D6F1B6835B8
F9AA2753-5293-44AE-8EC2-8D9624152DFA
6F2EFD73-5628-4042-8440-8D99FAB2CE41
76D2843E-67CC-44D1-9BCF-8E15102D4013
F1220A08-ED5B-4DE5-9F09-8E61B76779F0
741A4F64-7905-43DD-93FD-8EAE5E9A71CE
9BBBA96E-F3D3-4C30-939E-8EC21B67B50C
01D74270-A74D-4E8C-ACAF-8F76D136B2EC
9CC82546-3DBF-4883-BAA5-8F7C630C7932
9224D173-8E5C-48E0-BA32-8FB957075374
690B7E43-4BE8-4355-BD98-8FC0D975D640
69535C93-FE83-4886-9B38-8FDD618B5ECE
983EA937-079F-4ED0-8B51-8FED1E007F09
A2FCB000-5824-4417-B5B8-901689C0EF6C
9263C349-2B82-42C1-A915-90866353A50D
D9663B1D-A254-48C2-8A20-909EAEF5D1DD
F74D6311-EA6C-468C-9033-9147865083F6
DA69CF58-1A32-413D-9BDF-93545F86896B
9ABEB0D5-1BC7-4317-90C1-9356FB5196D1
1F9BF498-876F-4D71-8A20-938A440CC524
C867BA2B-AF55-4829-96F6-94095BEC7D20
2EBE23B4-23F5-4C02-B3CA-940C65E743BA
0C2B26A4-8EB7-47F2-A870-94E4333073DF
CDCF3908-2CDE-41CA-AE97-950110D9D79E
F356AD8D-FB07-4847-BC5D-9520F08A473B
1C189087-F921-48E8-95DD-95D2FE4F0290
A845EF07-EB3C-476C-AC9C-969210A07A58
C745BC12-D2CC-4ABF-B115-975FE36CE8DE
3AC8DC94-E747-454A-8EA4-9793E6911877
9B0B7023-A08F-43B9-A186-9796D98B227A
AAB3AB34-88D3-4BED-AF49-97DD55AC8436
1DD6376E-8477-4B2B-8E5E-983F366F5E75
7A84F683-33A5-4DAE-8673-9861F240EC1E
809FD078-CBC8-4459-80A3-98F9375585DD
7C71D2CF-D582-4925-A0E8-991540B1F758
A7722373-9618-41A1-ADA9-9919F0FD664F
0926EA29-8640-424A-BCAC-99846CFB9F43
80A5E9DD-C907-46F1-A0C6-99E69CBF55B9
58A66A5E-0654-4AB4-9883-9A4573E57F02
80160AB0-2A11-44DD-A456-9A8B44A7E0A1
A4C4BF6E-9122-451D-B93F-9A8D3B41B454
3F61D8DD-4AF8-418B-8698-9AA6C4EC0B87
7A11BBB2-10FE-4B25-825C-9AE69A7C672F
35B1D4F2-F4FF-42BB-95BE-9B19ECD4FF75
2FC4157F-DFEA-4655-9B96-9B1B0F2AB65E
826F64F5-5C71-4F30-9BDF-9B2485E60372
1FBFBF32-4A4E-4AFB-ADD9-9B335B31D3B2
57D81C95-78BC-4285-839E-9B97B333F4A8
2518AD00-B193-46C9-A261-9BEB4E2D5E06
2DA3E695-65AD-439F-A0BD-9C3BC1F9AE39
FBE6C2E9-7E1A-4830-A563-9C3E1A85387E
637E9C61-398F-4CFB-87CB-9CE0FCBCB1FA
34C8BB62-AB1A-427C-ACA9-9E1BB5DBFEBD
A470BA02-F8E7-471E-AFA2-9E1D56938F37
2782F362-F2DF-4003-9132-9EDA47941632
926B9F28-1882-4899-84BA-9F23F871EE91
370AACC8-90A7-4B8B-8849-A0762ED12F8A
588A1ED5-7E46-4986-9181-A08C90799D73
0B546560-8C13-4F37-8C21-A08DFFB4E8A4
828DF726-5C67-43AD-B9CF-A090FF06624C
5C94473A-DD1D-464C-83CB-A0E34D11481A
1E8B1C3E-CBA1-4F8B-A265-A122BD82B2E8
11175281-B01A-4544-93AE-A236CC391533
F8DE1E30-A50E-4D21-9B05-A321999100C6
1F08F0BA-7D03-43CE-BF42-A3728554CD55
72973409-4A7C-4D54-9D37-A3AC933B06F1
36E17BAC-F5A0-438D-A40E-A3B36DB77769
7976362A-4013-4BA1-BD19-A3F8079580E1
5AF506A6-4256-4D1A-872B-A465F41DCDA8
984B12D4-6171-413D-828D-A4C40DD4D2F1
8BCECC4A-AE22-4296-BC14-A4F629525A96
F4407B5A-B09D-40E7-967E-A51B1D4D5C49
B3C5A03E-892B-4C2E-A6BE-A53298E94679
BA351556-1D26-4832-AD38-A5E54BD35670
F73C3625-F679-4F53-A831-A5EDF6B2E4D7
5877D3FA-1995-400F-AF1B-A63ACDA8E063
33C9DFB0-699A-4B56-B105-A6401AA2E829
C6C95B3C-E273-4656-A669-A69EB9FD10A9
C0C56683-E12D-4B7E-887F-A6AB04A52473
97BCB9ED-7F9E-4E10-B37C-A6D429EAF0AC
6F56F5F0-0335-442D-B8DC-A72C55430B4C
7ED93C4E-139C-4B8B-9897-A7301E7AF78C
9C50D074-B01B-4584-B8E8-A75F8E83A4E0
C8848DDA-7711-4E5B-969C-A7E65B3DA82F
4472BA95-8947-415F-B427-A842E82B0DA6
BA15835D-4425-4673-898E-A8AE09FAC1EC
602E0818-90D5-4637-99D4-A8B7A42293A3
80AC8ECF-BE7B-4F5B-908A-A8F9F9A7C3CF
6AA068D6-3545-4EA6-BCEB-A92E8B8F7512
530D60FD-015A-4542-8080-A9417E6D626D
2D0844D5-0244-4D40-A7D9-A9614524C2A4
7E9E6A05-DE92-4F4C-9ABA-A984CF36E19D
D35309EF-1BE4-4098-95AE-AA0757BE99F0
9C79BBF7-A52B-4B20-8B51-AA3EBC3B705F
B09C2715-2754-4FB8-8AAD-AA89D2BF21E0
2E6CB9EA-227F-43E2-8E58-AAD41792B1D4
AE56E183-161A-43D2-A9C1-AB032983452D
AEBC99F5-5B15-43A9-B127-AB67CE688072
FC43DCD1-D99B-4246-A57C-ABAF9C8A07A4
EE7AC54F-0AA5-4296-9BFD-ABB3BE7D2D90
6C70125E-CFC3-446F-B9E5-ABC95908BFD6
90DB43C7-3FE5-488E-8D90-ABF28A53F6F2
9AD9FC71-6AE4-4B28-9A67-AC45DEA01FDF
83C1DE6A-E9CA-4440-8A73-AC9F3D3D061D
08196195-2FB8-4635-9751-ACF0965B8309
CA0127F5-4552-4167-92EC-ACFE3D63571E
330C8680-F06E-4692-9C93-AD604062382A
D58B2414-84BD-407D-9158-AD8F705A09B2
2962C969-8F63-4082-8B9B-ADB2065C3B05
4B77943B-3B2B-415C-8777-AE14634632F3
2B82FF1D-E21D-4DB5-A551-AE2EA7360A80
832BD55E-5FB2-4CE9-8107-AE450D312F49
54B45B0B-DFE8-48D7-85B8-AEE7E9494974
D6E7F019-385B-43F3-96CD-AEF1799917EE
6307433B-E5C5-4ECA-961B-AEF5EB404BE6
9DA04902-612D-4CAC-8B0A-AF3A6DCCD39C
D6C0A1D2-E623-4CE0-9649-AF87C4B01EAC
74B3A1F9-BF61-4B95-95C7-AF92C30BF4CC
5B1C7847-EEDE-42C7-9DCF-AF9801391428
C905F6A6-418C-4E29-A94E-AFA2AEC073AE
0F9A3112-C6FD-46AD-A5B6-AFA56EF2EF53
1036E533-295E-4C1C-B68D-AFB4BCF198DB
CEECFD1F-FAEC-499B-87CD-AFB8223EB48C
B17A6DD0-1362-47BA-9C52-AFD14DB51BF0
F4A12E83-E126-4688-84E2-B00615ACB56B
0D098B76-7079-48EB-9D2E-B0E369E0BA3A
E427E82A-4916-47C7-9CD3-B0F62B142A20
C0E859BF-534F-468A-BB3B-B1028AF45ABE
129AC991-F8A4-4960-B8DA-B1238C76AF88
0CAECB5D-77A8-46B9-AB8B-B1EE12DA0F5D
C6AEB065-A116-4CED-9886-B1F699400341
A70A3656-BC23-4AF3-A8CE-B21BCE05233D
51DB1060-DE31-45C6-9207-B2602BF1E8B2
506AAFD7-451D-473F-9A98-B28EE5D0C7DE
81AA7807-F314-48FA-A801-B2BC0316342A
7459FC8B-F193-4DC7-B054-B2D47494F9DB
60DB6C08-66F5-437E-8575-B3B308FFF30C
8DDF4C8F-0D60-4499-B0D9-B44F835A531D
955D7BB9-5352-41EB-A82A-B4AF9E0182A4
A0876D1B-83D2-445D-A523-B4C7126ADCE2
689E310A-D951-4B1E-A13E-B5F1389A5506
A1E7AE1D-7223-4881-ADE9-B7004F3BD25F
3B59B44C-6A52-4FA9-8500-B725F24F2645
3D6C036A-E28C-4EF5-AF04-B76ED904C61C
CD132F71-739C-4FA8-B1E0-B781AD142496
5AF740B3-68DF-445B-882B-B78DF99915ED
13268FCE-981E-4B23-A052-B870816F2FEF
17930AAF-445F-41F6-B93C-B87D21676682
FFB7A6F4-4B1D-4223-B3FB-B9001AEA33E6
F6599294-3002-424F-BFE6-B9130A9C55A5
5D35DC30-7DF6-43D8-8AE4-BA28C90DF07C
C09DB589-40C0-48FA-AB86-BA38D111FB53
967D75DD-9D0A-42ED-BA83-BA67010CAE97
C51C17B1-1747-4EA9-B905-BAD03251EA7F
34E22F00-0D51-4EF0-A72E-BB22D5BA09A2
6CDA3B2E-1168-4208-9969-BB25A3C33005
BE5DB41B-1131-4BE4-AE48-BB3490B22C51
75B90A52-0AC8-4BA1-BEF1-BB59187C4014
B5680DC3-17F2-4BED-8DFB-BB66084D9B1B
5C5D1E4C-BB75-491A-9192-BB83FFD8C862
BDEC1EAF-DEB4-4E3E-8DA5-BB9649274735
66CAF854-C632-46E7-8755-BBD20EEBF0A3
FC853869-13BB-47AF-BB77-BC163E6CD042
E78BD496-9F5C-4BBA-9259-BC3BF1050872
696EF7C8-FAEC-4CCF-8F6E-BCB8769D7AD9
C003C2EF-E018-4C9C-BCA0-BCC340E44DA2
A2CDFE26-6AAE-4D91-B35D-BCCD069D1496
68D6A826-A674-48CC-901B-BD21CDDD3453
A67E84FC-5D3C-4EC2-B12A-BDB7E1CF15D4
D860464D-D645-435E-BB88-BDC7C2B91B6F
973D95C2-8000-43E0-A405-BDF46293B43A
488AF510-4C49-4589-AC1D-BE4066AA032E
63A1176A-F2F6-4601-BFE8-BF1B4F5F4AAB
6EB08024-75EF-4E2F-944E-BF4928A3A6B5
70110BBF-8A5D-4D12-AD58-BF817C9A2639
3DBB4986-E97B-408C-A282-C01DB3660AB9
41299D33-16F3-4234-BBB7-C038B4022152
C6D5662C-5D8C-40FC-AC13-C042BE488BF6
5EA24C0F-794E-48A1-81D7-C044924AA7FF
8CA7A3CD-EEA7-47F4-B941-C087DA6664A4
582A1B22-110D-4B1E-A100-C112519F44C6
296E1D73-1BD2-4200-A71D-C14B124D44A8
609ECA80-952F-46B3-8A2E-C196999FDEAC
7C590EC4-8C8F-43C3-865A-C2ACD67902B5
3CAA47EB-AFC8-43A3-ACC0-C308F21947C7
87552BB9-BA6B-491B-A9C9-C34C72316D8C
A21D5243-BF25-4CA3-ACBC-C397559458F5
E43B77FD-946C-48D4-8135-C39A4341963A
06089006-DE25-4A49-A6EC-C3E60DAAF005
35B679D9-8080-447F-8A6C-C41494E86EA6
2E7DCB94-496A-45B5-8B71-C430453FB5BF
7CF2F7A9-BA1A-4F0F-95D0-C46DCDE40412
C15A863E-7352-485D-9B72-C47AA79454BB
0E48726B-B3AF-43E5-905F-C4CF01900BA5
A2023CC4-B40F-466E-ADBF-C4D94E012E01
B5C6FBD8-5F0C-4E9E-B79B-C524CA576CBD
AACFBF15-F26E-46D9-80AC-C52B5F89C497
7EC3D258-DAB1-4DFB-820A-C54BA58834CA
F7DDC679-6237-4A94-97F3-C581CB3DF241
50AD127A-0714-47B2-8328-C59970C95066
21621BD1-7909-4C80-BB12-C5A8A05F54E4
6FACBD3D-8191-4D3B-A109-C62178000B79
AC1AB468-D869-43AB-BF1F-C6583230BA58
1E6869E2-9808-4A0E-8267-C6632F8AF5AA
43D89485-EB22-449E-A462-C693AF4524CC
72F94123-B8AB-4BAA-80AF-C6A48AD82F83
BECDBE4E-0DA7-469B-925D-C6E679D89B99
26B3B862-16AA-4A3C-9103-C6EA7D0CAFD3
38F24113-50CE-4036-999B-C70F654E9CD8
1885C35F-FFDE-4726-91BE-C7733A801342
309FC721-CDCB-454A-BBA0-C78BD92457E6
CF3B6A6A-75BB-475C-9B6E-C7A5BE7AD6FF
4743F3AB-177B-41CB-827A-C7F75BFEE4ED
04B86B8D-5C53-4F2B-922D-C8FEA81D7E85
EDBACDD8-1CF9-48A0-A17D-C9B2323C42F1
24B3F844-0317-4276-AC96-C9E5AC1F0ED5
F33D26F5-FD79-4E3B-8E92-CA53C9ADBB43
A3F1CD17-2ADA-4C80-88A3-CA7E2D03E42D
3BE83F25-AF46-45A9-ACA2-CA95CAEA82F5
B93EA506-7C3E-46F1-8C8C-CAD2032E735C
F8362B72-54E9-4B0E-B3B4-CB020FB74160
B44EEBCD-702B-4390-8FB4-CB27591D20C2
8AAF30D3-947C-4872-AD26-CB2C5A04E16C
1BCC2EE6-B5D6-4B24-AAD7-CB57D6370BE5
DD84C22D-06D0-4E70-9864-CB82D63B4603
6D3F6692-3C73-4B19-82F3-CBC7FE23022C
43FFC99D-D7DF-4766-95A7-CC1DACDF5007
D7C9D50A-D11A-4DA5-8D18-CCB197AD221A
C96ED3E4-3A0F-4CEC-9955-CCDB307A3014
7DBD33BA-C152-44D6-812B-CD2874CECD4F
9832DD2C-63EC-45BD-BE42-CD39B11224F2
280CABE0-759F-4D0D-BB9C-CD5267FDD89B
F87FA6F2-A689-4CCF-ABB5-CDF2F91A4935
4A344BFC-C1CD-4862-A4B9-CE2874F32258
6D691808-3B7F-467E-9890-CEB300A3F184
E4BEBB30-E255-47A1-8B16-CF4359723082
1C2F1991-C6BF-469F-9108-CF9C392204CB
778C46FC-73C9-40DF-A068-CFC8A4F84AB1
2CDF4303-E584-44A3-836C-CFF4EB95680D
CC18E2FA-44BD-4075-A2CD-D0248B74C3E1
3168CD68-7641-4CC1-92DB-D025B1CE5605
9032B29F-94A2-4D30-8C1B-D0E328F0E35D
4C25B31E-DBE7-4F6A-B95E-D10B92C924BF
BBBA3D56-4797-4241-BA4D-D1120F28E77E
AA29908C-ED9E-4B42-B9D7-D12E8B890ABF
0EC7F221-DE05-4EA7-A70B-D15329E34F67
FD59C1DC-65B8-4CD3-84D6-D1A5EAEC1EFE
2C9CA283-597D-4237-A03F-D1CE343196C7
7F2EC89D-9D21-4DDA-8233-D29A78444A5A
BAB50D11-D992-4246-B61E-D2E2FAD3BE2E
7E50D749-ABC9-4D3E-9005-D2E6F8D630BD
BD5FCF07-81F5-4172-BA99-D2FF3ABAAFF1
17D942DB-1B39-4083-BD73-D37C8FB91AE7
58CCF418-3686-4A1B-B76D-D42BFE4AE356
DC569790-31C8-4EB3-BB7A-D43789F50906
95C63137-1C8D-4007-9A55-D450CD1EF27B
316FD453-F028-4DC6-8506-D460DBDA7644
52D726C9-240F-44FE-9B2A-D472D7618917
B82265E8-E19E-4CDE-8422-D4740CE036D3
4229665E-A024-4F9E-A7E2-D4A4489A1D70
0243E6B4-D267-4280-BE1D-D4A72C4B764C
0C67A0A1-9032-4DD0-AF9A-D537181BB414
B14EDC6B-14F1-499C-9DBB-D58FB494C6EE
B7DA3919-B71F-4899-81A9-D5BCCD38F1D9
69CFCC9E-4C02-4DBE-A3D1-D61432019ACE
C0A039E5-D7DA-48CC-B85D-D618645E1EAB
E48F77B2-EF10-4631-8390-D6417217F56A
FBD49A8D-9B08-4886-AFFE-D6B874F15930
CD7CB08D-20F2-4A59-B936-D6E5205A941B
EB031E1D-3117-4D66-831F-D6EFAF5D9DA4
5A81F8E2-1E5C-4DC2-BF55-D6F1E64AAEF0
D1C05D30-58E2-4130-A26D-D6FEEBEB99C9
99B12B91-9A22-406F-8C08-D7198CA8CD56
27DB57BB-1BAB-461A-94C6-D73EBF02CA51
FEA9F900-A109-47D1-9297-D74C54E12CA1
01D9C3A5-F838-4D53-9966-D76283C73E0E
2E6631B7-803E-4BC7-A2A6-D7C19B9E7452
C1B2A562-713B-4B1A-BAAD-D7EB36EAFD5A
145CA608-9A6C-4282-840F-D8A27AD85086
1307FC2F-9191-4958-9D42-D8B7F00DA78D
F665477B-EF3E-45C0-9943-D8C506ED3FBB
F8FC0EB8-1F16-4BA9-A03D-D9CD11F95156
86528331-6E5E-4962-B63A-DA0A9640B03D
C6ABC11A-64B1-41D6-B6A9-DA33C61C2A2C
7448A8A2-B241-44EE-978A-DA5E3D844507
39D590F0-BCAC-4C10-BA94-DA9BA558BA2C
883256D9-6CD8-4F9C-A73F-DAABFD541646
2EF58BB5-058C-4337-8BD6-DABA4CB6FE84
6CA1C5AA-92AF-4342-B6FC-DABDA1B1F7F7
1B620DE6-8653-4E31-A3E0-DABED4BD744E
47AD749E-0C47-48E7-961C-DAC0FEFD3E61
447B8525-CED9-4C52-922F-DAF7A2E53C69
79724B49-7D73-4B87-B27A-DB350063B5CB
3EF21BF9-6F38-48AE-AC66-DB41A860CA36
BC75AA4E-4BB4-4F77-9D18-DB5821BCC517
3E360C7B-66F3-4179-B0F5-DB61288E4513
FF290AC3-125F-4F38-B169-DB6287FD1CE1
48FDB73A-8185-480E-9150-DB63C65B3E44
003F552F-547A-4122-AAA5-DBAB3004F5A1
B3D526BA-3AE9-46FB-A449-DBE9EC798633
CD868490-0E6D-4F33-B76F-DBFC94A08FF3
DE463448-8B02-4201-8D79-DC322DAD2E65
0619A782-E34B-4F71-8422-DD12B1193565
9D822171-E286-4A75-83EF-DD2BBF6B0847
F38976D7-0515-464B-85E9-DD406C0BE865
70A0ADE3-CECE-49D7-B797-DE000D92A7CE
51C2D8B7-AFA0-4BB3-900F-DE0C6DB70DB2
35F40593-20C3-4A0A-ABD5-DF19D0F92FE1
AC328639-2D1D-44EB-9488-DF4E5C9374DE
33A7D8F3-326E-4FE8-8E7C-DF56FD991675
CE64BA78-6FB8-4097-A10E-DF9273E1F36D
BE0F393C-F80A-432C-9EFF-DFCC547E20D3
1A247825-3669-4E1B-B574-E10627A2A134
62EB6387-3E60-4CCB-9FFA-E147A21DA9AE
FA8427B0-A661-4DA4-8005-E16031ECEDAE
11A847DF-3C0C-4D9B-A6D4-E23E0AFE8C7A
B9E62C17-B346-4DDC-98FB-E24FE4C65171
2A8E709C-6910-451F-B457-E28C9B0D7A25
39C3269D-FE6A-44C6-9A66-E29E1A87919D
9683C8B7-E4EC-4D7D-9909-E2C09F4DFEF3
50A4F805-C4E8-4574-8D77-E2DAB599F27D
B429D6CC-7C26-41CF-871F-E31CCF048135
F2783DF1-52DE-491C-B618-E34FB584A552
05DF5206-88F3-4BFF-9ECB-E36E45B8E439
F4E227FD-CD80-4167-84FA-E3A6F7525B3F
1FF05D6C-12A8-432E-AE1E-E46EA3EFFC3D
AE6A08E1-C42D-4FCD-9308-E482005E4C03
52CD1C32-63A2-478C-A27C-E49BBFE487E1
FFE1EFF5-77E7-4626-A440-E4C05820D9F9
04F6E57B-9B73-4793-A8B3-E4D0B6B38CAF
DC2FE53F-8375-454D-8154-E51AA93B2221
F2D70747-AF31-42BF-B341-E5F029D0588F
5B670C89-A516-4104-A9B0-E6007434EC0C
32BC171B-6D58-45EC-8EAA-E617D08C16D9
1DC0CA64-FA0F-4859-BC79-E6816EEF45AE
F22F9307-EDB1-4FB2-A070-E6B36F9808E8
425A3617-6A12-492D-99CE-E6E2CE9AAAB3
B16B721F-2467-43B1-BA68-E7332DC36400
A76448B6-CDC7-4D23-88E8-E7386409ABF9
15F06082-6001-4945-BD38-E757427A577F
2D67D83D-D6D2-4645-9575-E81A79E08EE2
B3E8F2E5-FFA0-4D63-B9C4-E87D9511F63F
DD30E7E5-9FDF-44B6-B1C3-E881C77AD2E6
8EDB099F-D4C8-4F37-AF33-E91628985AF1
CED4D775-C831-4694-AA83-E95F420F87A9
03BDF3B3-19E4-494C-B8A6-E996F8779571
002F8C98-0375-4228-9D73-EA8A7190976F
DDC9203A-F1EE-40E5-A9F2-EAC7EA9D25F6
3D83371A-3926-4156-9720-EB3AC0E20F39
71066F7C-248A-468A-8B1E-EB7E8F78492B
9F075644-D2D5-4494-83FE-EB834C89A8FA
6A30A41E-1FAD-4DE2-80CB-EB8EF63756F9
DD4AD4DB-3CBC-4A32-956F-ECE6589BF97E
21CA0F8C-6F2C-4F12-9D34-ECE9249BC8C6
F6D10710-AFDE-4156-AFFF-ECF0CE2E6599
9AC4EC10-B8B9-41C6-89E0-ED22FCF0083A
51415F48-7EB8-4F00-93AB-ED3A43440B93
CA0A3295-05E0-4D43-A33F-ED4EC5F7F2E0
EEB78BEA-C55D-4AD1-A34F-EDB340F23387
9EC734BB-AA1B-4B5D-A464-EDD4078539FF
D931DA60-6AF5-406E-A59C-EE1F1492DE15
13A7B028-A761-4E22-B4FE-EE6CDE6D9DFB
6BB07281-BC1E-40D2-933A-EE74124095B6
957BBE9D-ABDA-4C3B-AD6F-EE820E3E6305
7B147143-8E06-48ED-86B6-EE8F045CCA27
E620B007-90AC-4857-A7ED-EE978F7386D2
931DB31B-46D7-4596-8C3A-EE9F9372A18D
D56A4BD9-0C7C-4840-975E-EEB8E56D4023
712C878F-DB61-4888-B3B0-EF7F02B277FE
E5D395C0-CCC9-4DAA-B13C-EF85EFFF78DA
AEADA2EA-D04B-4996-A73E-F107C2C2A6D8
A4133124-9FCB-464C-B66F-F159F055F748
3140E3EC-9F7E-47BA-8B40-F16860ADA317
41436D44-2F76-484E-A4AA-F18D46BB2E0C
2D7E6E40-A76E-44E2-8BC3-F1C8A45BBD9E
ADC35B51-B48E-49DC-A641-F2522BF0D81B
DE281C0B-C91B-446A-989E-F25F4299A2AD
98D2F074-2F1D-47BD-949D-F29D9AE7696B
AB44DE26-90B2-4CDE-AC78-F302CDAF20A4
C4002DB0-74BA-43E7-BD78-F3670FF0DD17
742E843C-D0DD-4EBA-943E-F39703155627
0E6E8429-F083-4A92-B3C1-F49C6846FA63
26843435-8DA8-460D-B3F3-F5029E71709C
A2A93468-155E-4144-A046-F5374C1E829C
16A0A763-1D72-4738-8615-F54BB7BF7089
940F2A77-1FFA-4297-8987-F5799A2C9183
3828D53D-0F38-4142-AE59-F5A9055A5CAE
5DCB6B05-AE08-4E15-B025-F6228AE3EB3C
7DB098D1-F48C-419D-B6D5-F7887CBD5090
FA122B03-ED1B-40BF-A382-F7BCCE956773
4EF57CE1-71DA-4B87-982B-F7E7BDC4BF24
CBCFC3CA-135E-41D0-A99B-F805B5AE897E
E0D6A0B4-E49F-481E-9001-F830BBE7239C
A4F05F59-D045-41C5-9C1F-F8358E085072
85590FE7-B54E-4EB4-A749-F84BB1BC85DE
6980A0A0-F9C0-4113-A950-F93075921694
FC262060-B081-4348-85FE-F9551CEA3D05
5D8F1649-09A2-4AF1-9B3C-F9651844F25B
3DEACD34-8257-47CA-AAF0-FA02B06E941A
DF09AC26-C898-42E2-B934-FA811432847D
0C87F278-2BE3-4D3A-8432-FABDCCB2ADF6
5D962F85-2BE1-4C56-8200-FABFB986094C
33A4A63B-C325-40F8-8A28-FB916B03F961
DF09AE05-AAB7-4D59-B285-FC0F309A628F
4C632347-EA5E-41AF-A945-FC71826F978A
A5DA89E8-23A0-4581-B2A6-FCDEB1D7AC8C
EABCE0D8-955A-4F09-B0BE-FD277EAB8132
E28E47AE-D5B9-40C8-B725-FD2959347FDB
7335EF57-A2AF-41E3-95D3-FD3F315BB888
71BFC6C6-0FD8-4FCA-87ED-FD7ED63604E1
243BFE4F-8174-4A6A-87CB-FD835C99C4B8
3DB79D8A-20DF-4B77-B4D3-FD8864EAC639
3B02B28E-7053-460F-B21C-FE5F12695B3E
A1CA7225-E7A5-4872-93DE-FEA15D4BD4F2
849A9A33-CCBD-4498-B96E-FF3AE4ED4FD9
58A1027E-8AE1-4855-9CC4-FF3D560E1448
9EF2DE44-1230-49B9-BB73-FF8E74AC0DC0
BD953131-97F1-4B80-89F6-FFD4702274E4
5B1CCE6E-3833-45C2-B0EB-FFE568483DBB

Hugo Kornelis

unread,
May 24, 2006, 7:18:37 PM5/24/06
to
On Wed, 24 May 2006 14:55:14 -0500, NumbLock wrote:

>So the optimizer can read your mind? What it says is that the data is
>already ordered if you use an order by. How much clearer can that be?

Hi Galen,

What this means is NOT that the data will also be returned sorted when
not using an order by.

What this DOES mean is:

- IF you specify an ORDER BY,
- AND the optimizer decides to use the clustered index,
- THEN no additional sort step is needed, because traversing the
clustered index pages in logical order (by their pointer chain) will
result in the rows being read in the required order.

This might of course result in a faster execution.

However, the optimizer is still free to choose a different index (though
it will have to add a sort step in that case).

Without the ORDER BY, the optimizer will be even more likely to choose a
different index, since it can do so without the required extra sort
step.


Of course, you are right not to believe what people say on face value.
(Though you should IMO apply the same critical attitude to what you read
in Books Online). The truth can only be found by testing.
In other posts, you've been saying that if you query a column with a
clustered index for a range, the result will always be ordered by that
clustered index. Below is a script to prove that this is not true.

CREATE TABLE test
(Cluster int NOT NULL,
Other int NOT NULL,
Filler char(2000) NOT NULL,
PRIMARY KEY CLUSTERED (Cluster));
go
CREATE INDEX ix_Other ON test(Other);
go
DECLARE @i int;
SET @i = 1;
WHILE @i < 10000
BEGIN
INSERT INTO test (Cluster, Other, Filler)
SELECT @i, CASE WHEN @i % 789 = 0 THEN @i % 987 ELSE 0 END, '';
SET @i = @i + 1;
END;
go
PRINT 'Without order by:';
SELECT Cluster, Other
FROM test
WHERE Cluster BETWEEN 100 AND 4500
AND Other > 0;
go
PRINT 'With order by:';
SELECT Cluster, Other
FROM test
WHERE Cluster BETWEEN 100 AND 4500
AND Other > 0
ORDER BY Cluster;
go
DROP TABLE test;
go

Results (on SQL Server 2005 and SQL Server 2000 SP4):

Without order by:
Cluster Other
----------- -----------
3156 195
2367 393
1578 591
789 789
3945 984

With order by:
Cluster Other
----------- -----------
789 789
1578 591
2367 393
3156 195
3945 984


--
Hugo Kornelis, SQL Server MVP

Stu

unread,
May 24, 2006, 7:25:05 PM5/24/06
to
Aw, Hugo, I thought you had him for a second, but unfotunately he has
apparantly narrowed the scope of his original statement. In other
words, according to him, a test will only be valid IF the following
conditions are met:

1. There must be a clustered index
2. The WHERE clause must reference the columns in the index AND no
other columns covered by an additional index.
3. The SELECT statement cannot contain aggragates.

Just pointing it out, because it took me several posts of his to
ascertain those conditions.

Stu

Dan

unread,
May 24, 2006, 7:33:32 PM5/24/06
to
It works fine on my system. It may be a configuration issue. I am running
on a mulitprocessor system. Without a ORDER BY clause on the ID column the
rows do not come out in order. 1000 rows isn't enough to see the effect,
on my system if there are only 1000 rows the result always comes out in order
on my system too.

Dan

NumbLock

unread,
May 24, 2006, 7:38:29 PM5/24/06
to
This is what I needed to see. I agree that you have proved my statement
wrong. This is what I consider to be *expert*. Someone who can back up
their claim. Why don't you write a book, Hugo?

Hugo Kornelis

unread,
May 24, 2006, 7:40:10 PM5/24/06
to

Hi Stu,

My goal was not to "have" anyone - I believe we are all here to learn or
to share knowledge - both in my case!

I may well have missed some points. I've just been reading the entire
thread and I didn't check every detail.

If the requirements are as you state, it will be hard to post a repro.
But I still feel uncomfortable leaving off the ORDER BY. There is at
least one situation (unfortunately not something you can reproduce on a
test system) that might mess up the order of results. I once caught a
post by someone from the MS team who helped building the optimizer and
query engine that mentioned a rare optimization technique. Suppose you
submit a query that forces a clustered index scan. Just a split second
later, I submit my query that has to scan the same index. If my query
has no ORDER BY, the engine will let my query "look over your shoulder",
picking up data from the pages read for your query. Once your query is
done, my query will go back to the first page of the clustered index and
start reading until it gets to the point where it started looking over
your shoulder.

That would ruin the expected ordering. It would only happen on very busy
systems. And only intermittently. Very nasty bug to track down!!

BTW, I also think that Galen aka NumbLock makes some very valid points.
Way to many books just claim that a clustered index controls the
physical ordering of the data, where in reality it stores data in a
pointer chain that is logically ordered (if you follow the pointers),
but can physically be scattered all around the DB. And way to many books
state things that might mislead one into thinking that the results from
a query that uses a clustered index will always be ordered. The point
that Galen takes in this thread is incorrect - but it's very easy to see
how he has come to his conclusions. The writers of BOL and the authors
of several books are to blame. As are many frequent usenet posters (me
probably included).

NumbLock

unread,
May 24, 2006, 7:42:10 PM5/24/06
to
My original statement was and is that a if you omit the order by clause
on a column which has a clustered index on it, it would always come back
in index order. I said an index on another column would effect the
outcome. But Hugo did not use any other columns in his where clause, he
used only the between clause on the clustered column. Directly
disproving what I thought to be true.

NumbLock

unread,
May 24, 2006, 7:45:58 PM5/24/06
to
Further, even if you omit the AND other > 0 it still has the last couple
of rows out of order. But if you do a select * instead of specifying a
column list, it comes back in index order. Still, I have been proved
wrong. Thanks for enlightening me.

Hugo Kornelis

unread,
May 24, 2006, 7:48:54 PM5/24/06
to
On Thu, 25 May 2006 01:40:10 +0200, Hugo Kornelis wrote:

(snip)


> There is at
>least one situation (unfortunately not something you can reproduce on a
>test system) that might mess up the order of results.

Afterthought....

After reading Dan's latest post, I realize that I have missed a
situation. One that would be easier to repro.

Use a multi-processor system with multiple drives. Set up a distributeed
partitioned view (on SQL 2000 or SQL 2005) or a partitioned table (SQL
2005 only) that uses multiple drives. Execute a query with a range
selection on the clustering/partitioning column, such that part of the
data is on one drive and part is on the other drive. I expect SQL Server
to come up with a plan that assigns two processors to each get matching
rows from one of the drives, then merge the results. It would be
unsorted.

Since it's almost 2AM in my time zone, I'll leave it to someone else to
post the actual SQL code to verify this expectation.

Hugo Kornelis

unread,
May 24, 2006, 7:54:02 PM5/24/06
to
On Wed, 24 May 2006 18:38:29 -0500, NumbLock wrote:

>This is what I needed to see. I agree that you have proved my statement
>wrong.

Hi Galen,

Thanks -- but according to Stu, I missed one of the requirements that
was hidden somewhere in this monster thread.

> This is what I consider to be *expert*. Someone who can back up
>their claim.

<blush>

Most of what I know about this comes from reading Kalen Delaney's books.
The rest is partially from reading postings by many other people who
have contributed to this thread and many who have not, and from
experimenting.

> Why don't you write a book, Hugo?

My native language is Dutch. Almost all Dutch SQL professionals are able
to read English quite easily. The market for Dutch SQL books is
non-existing.

Oh, and I have no time for it either. :-)

Hugo Kornelis

unread,
May 24, 2006, 7:58:30 PM5/24/06
to
On Wed, 24 May 2006 18:45:58 -0500, NumbLock wrote:

>Further, even if you omit the AND other > 0 it still has the last couple
>of rows out of order.

Hi Galen,

(checking)

Dang, you're right.

That one even managed to surprise me!

(It's logical once you understand the reason - I just didn't see it
coming).

Let me know if you need an explanation. I'm off to bed now, but I'll
gladly tell you why this happens tomorrow.

Kalen Delaney

unread,
May 24, 2006, 8:06:42 PM5/24/06
to
But I may be enlisting Hugo's help when I need to come up with examples for
my query tuning chapters!
:-)

--
HTH
Kalen Delaney, SQL Server MVP


"Hugo Kornelis" <hu...@perFact.REMOVETHIS.info.INVALID> wrote in message
news:e7s972lqq1so7li8b...@4ax.com...

Kalen Delaney

unread,
May 24, 2006, 8:07:56 PM5/24/06
to
This is a great example, Hugo. Thanks!
Might a just suggest putting SET NOCOUNT ON in it, though?

--
HTH
Kalen Delaney, SQL Server MVP


"Hugo Kornelis" <hu...@perFact.REMOVETHIS.info.INVALID> wrote in message

news:89p9721ung6nucnn4...@4ax.com...

Stu

unread,
May 24, 2006, 8:52:54 PM5/24/06
to

NumbLock wrote:
> My original statement was and is that a if you omit the order by clause
> on a column which has a clustered index on it, it would always come back
> in index order. I said an index on another column would effect the
> outcome. But Hugo did not use any other columns in his where clause, he
> used only the between clause on the clustered column. Directly
> disproving what I thought to be true.
>

SELECT Cluster, Other


FROM test
WHERE Cluster BETWEEN 100 AND 4500

AND Other > 0; -- What do you call this, if not an additional
column?


I'm sorry; I think you must be getting tired. I fail to see how Hugo's
query is substantially different than the first query I posted (several
hours ago).

Gert-Jan Strik

unread,
May 25, 2006, 7:39:19 AM5/25/06
to
I don't want to spoil the party, but I don't get it.

Hugo's query proves that the clustered index is not necessarily used if
you have a WHERE clause that filters on the clustered index's column!
Look at the query plan: no clustered index anywhere in sight.

And that is basic knowledge, since the optimizer simply makes a tradeoff
between the cost of using a nonclustered index (and potential bookmark
lookups) or following the clustered index.

In this case the tradeoff is extremely simple, since the nonclustered
index is covering the query and thus will require no bookmark lookups.
Sorry, but that is a no brainer.

Please note that the person you do recognize as being an export (Hugo)
also described that merry-go-round scans (on Enterprise Edition, as of
SQL Server 2000) could mess up the order of the clustered index scan, as
well as his excellent idea that a partitioned table on multiple disks
(as of SQL Server 2005) might do the same.

In the future I expect more innovations in the Storage Engine which will
increase performance and exacerbate this behavior.

Gert-Jan

NumbLock

unread,
May 25, 2006, 9:54:43 AM5/25/06
to
I neglected to mention here that if you leave off the AND other > 0 it
still comes back out of order in the last couple of rows. I did a
followup post to explain what I meant.

Do not worry. The coup against your self-professed expert status has
been put down. You can have your little newsgroup back now.

Stu

unread,
May 25, 2006, 10:30:20 AM5/25/06
to
Whatever. You're the one that claimed you liked a good argument; I
just wanted to point out a fallacythatt developed over the course of
your postings. You seem to be the only one whose feelings are hurt.

Numblock

unread,
May 25, 2006, 11:10:36 AM5/25/06
to
Kalen, I have agreed that Hugo has proved my theory incorrect.
However, based on our argument about the physical ordering of data in a
clustered index, msdn2 states the following at

http://msdn2.microsoft.com/en-us/library/ms190639.aspx

"Clustered indexes are not a good choice for the following attributes:

* Columns that undergo frequent changes
This causes in the whole row to move, because the Database Engine
must keep the data values of a row in physical order. This is an
important consideration in high-volume transaction processing systems in
which data is typically volatile."

This statement completely goes against what you and expert David Portas
and others have said about physical ordering of the data in a clustered
index.

I've seen that the results come back skewed in Hugo's example. Perhaps
you should use some of your contacts at MS to resolve this ambiguity.

Numblock

unread,
May 25, 2006, 11:25:40 AM5/25/06
to
Yet another quote about the physical ordering of a clustered index:
I understand the concept of a page split, but if a proper fill-factor is
maintained there should be no page splits. Isn't that correct?


This one from http://doc.ddart.net/mssql/sql70/8_des_05_5.htm

When you create a clustered index, the data in the table is stored in
the data pages of the database according to the order of the values in
the indexed columns. When new rows of data are inserted into the table
or the values in the indexed columns are changed, Microsoft® SQL Server™
may have to reorganize the storage of the data in the table to make room
for the new row and maintain the ordered storage of the data. This also
applies to nonclustered indexes; when data is added or changed, SQL
Server may have to reorganize the storage of the data in the
nonclustered index pages. When adding a new row to a full index page,
SQL Server will move approximately half the rows to a new page to make
room for the new row, a reorganization known as a page split. This can
impair performance and fragment the storage of the data in a table.

Numblock

unread,
May 25, 2006, 11:42:01 AM5/25/06
to
Yes stu... Both of my feelings are hurt. :) If you are gonna call
yourself an expert, you will have to prove it in my book. And I do
love a good argument. Fact is what I said about your query was true.
It is loading more messages.
0 new messages