邹兄!救急!!!关于非聚集索引排序问题

路人乙e 2010-12-28 02:12:02
一个user表,包含如下索引,都是非聚集的


查询语句A:
SELECT TOP 100 UserId FROM User

得到如下结果

是按UserId排的序

查询语句B:
SELECT TOP 100 UserId,Username FROM User

得到如下结果

看上去是按Username排的序,但接着看如下语句

查询语句C:
SELECT TOP 100 UserId,Username FROM User ORDER BY Username

得到如下结果

确实是按Username排序,是在全表中排序后查询top 200,而语句B貌似是top 200后的order by Username

这是怎么回事呢,SQL总得有一种默认排序方式吧,到底是怎么排的序
...全文
311 31 打赏 收藏 转发到动态 举报
写回复
用AI写文章
31 条回复
切换为时间正序
请发表友善的回复…
发表回复
feilniu 2010-12-30
  • 打赏
  • 举报
回复
总而言之就是:

如果想要使查询的结果顺序固定,则必须指定ORDER BY。
否则,结果顺序由数据的物理存储形式和查询引擎选择的执行计划决定。
xiaoxiangqing 2010-12-30
  • 打赏
  • 举报
回复
最好自己指定排序
feilniu 2010-12-30
  • 打赏
  • 举报
回复
没有聚焦索引的堆,就是一堆页的线性链表。默认是插入顺序,如果更新和删除导致页面重组,顺序就会改变。
feilniu 2010-12-29
  • 打赏
  • 举报
回复
SELECT TOP 100 UserId FROM User
====
IX_UserID的Non-clustered Index Scan,扫出前100,按索引默认顺序输出。

SELECT TOP 100 UserId,Username FROM User
====
无聚集索引,则是Table Scan,扫出前100,按堆默认顺序输出。

SELECT TOP 100 UserId,Username FROM User ORDER BY Username
====
估计是IX_Username的Non-clustered Index Scan,扫出前100,再Table Lookup,找到对应UserId,强制按Username顺序输出。
Q315054403 2010-12-29
  • 打赏
  • 举报
回复
因为查询的内容有从索引得数据,有从索引+Seek得数据,所以不同喽
renwenli07461 2010-12-29
  • 打赏
  • 举报
回复
执行计划执行的是怎样的呢,可以找出原因
-晴天 2010-12-29
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 sq_zhuyi 的回复:]
引用 6 楼 haiwer 的回复:
前两个语句,没有order by的top,返回的纪录是不确定的,这是你写法的问题造成的

NO,是确定的!
没有order by每次查询返回结果一致,无论top多少
[/Quote]
当发生 insert update 时,数据排序就可能会变化.
路人乙e 2010-12-29
  • 打赏
  • 举报
回复
[Quote=引用 26 楼 feilniu 的回复:]
SELECT TOP 100 UserId FROM User
====
IX_UserID的Non-clustered Index Scan,扫出前100,按索引默认顺序输出。

SELECT TOP 100 UserId,Username FROM User
====
无聚集索引,则是Table Scan,扫出前100,按堆默认顺序输出。

SELECT TOP 100 UserId,Username FROM User ORDER BY Username
====
估计是IX_Username的Non-clustered Index Scan,扫出前100,再Table Lookup,找到对应UserId,强制按Username顺序输出。
[/Quote]
一点不错,是这样,但SQL堆的排序却是一大问题,到底怎么排序的呢?非插入,非更新,非索引
starseeker7 2010-12-28
  • 打赏
  • 举报
回复
再补充下
当你再删除索引- -
查询结果又回复原来效果
select top 100 id,col1 from t2
效果又于select top 100 * from t2相同
看来应该是若查询中只包含索引列,,,就会按索引列走
若不完全是索引列,,就是默认吧
starseeker7 2010-12-28
  • 打赏
  • 举报
回复
初步测试8楼说得是正确的-w-
以下是测试数据- -


CREATE TABLE [dbo].[T2](
[id] [int] NULL,
[col1] [char](5) COLLATE Chinese_Taiwan_Bopomofo_CI_AS NULL,
[col2] [char](5) COLLATE Chinese_Taiwan_Bopomofo_CI_AS NULL
) ON [PRIMARY]

go

declare @i int
set @i=1
while (@i<5)
begin
insert t2
select @i,cast (@i as varchar)+'a',cast (@i as varchar)+'0b'
set @i=@i+1
end
go

insert t2
select 0,'0a','0b'

go


select top 100 * from t2
select top 100 id from t2
select top 100 id from t2 order by id

go


/*
id col1 col2
----------- ----- -----
1 1a 10b
2 2a 20b
3 3a 30b
4 4a 40b
0 0a 0b

(5 行受影响)

id
-----------
1
2
3
4
0

(5 行受影响)

id
-----------
0
1
2
3
4

(5 行受影响)
*/

create nonclustered
index IX_1 on t2(id asc)

select top 100 * from t2
select top 100 id from t2
select top 100 id from t2 order by id

/*
id col1 col2
----------- ------ ------
1 1a 10b
2 2a 20b
3 3a 30b
4 4a 40b
0 0a 0b

(5 行受影响)

id
-----------
0
1
2
3
4

(5 行受影响)

id
-----------
0
1
2
3
4

(5 行受影响)


*/


xyytuo 2010-12-28
  • 打赏
  • 举报
回复
王向飞 2010-12-28
  • 打赏
  • 举报
回复
需要你做两件事所花的时间肯定大于做一件事的时间,并且是分先后的。讨论此问题没意义
叶子 2010-12-28
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 yhtapmys 的回复:]
江湖上还有邹老大的传说
[/Quote]
邹老大远离江湖了
yhtapmys 2010-12-28
  • 打赏
  • 举报
回复
江湖上还有邹老大的传说
lixiaocai123 2010-12-28
  • 打赏
  • 举报
回复
排序肯定花时间
billpu 2010-12-28
  • 打赏
  • 举报
回复
如果你不加order by 那表里至少定个聚集索引 决定你的物理排序
abuying 2010-12-28
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 coleling 的回复:]

引用楼主 sq_zhuyi 的回复:
这是怎么回事呢,SQL总得有一种默认排序方式吧,到底是怎么排的序


1.一个表在没有聚集索引的情况下,默认是按插入数据的先后来排序的(但Microsoft并不保证总是如此).
2.在存在索引覆盖时,SQL Server将只读取索引页,而不读取数据页,即在这种情况下,返回的是索引的顺序。

具体到你这里,
语句A: SELECT TOP 10……
[/Quote]
邹兄就是邹健大哥!
nzperfect 2010-12-28
  • 打赏
  • 举报
回复
你这样的用户表,应该有聚集索引。
另外,你的
SELECT TOP 100 UserId,Username FROM User ORDER BY Username
索引应该为:
create index ix_Username_userid on User(Username)include(Userid)
nzperfect 2010-12-28
  • 打赏
  • 举报
回复
排序本来就应该写order by ,不要指望sql的逻辑排序。
nzperfect 2010-12-28
  • 打赏
  • 举报
回复
select * from users 不需要排序
select * from users order by username 是需要排序的

时间当然不一样喽
加载更多回复(11)

22,209

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 疑难问题
社区管理员
  • 疑难问题社区
  • 尘觉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧