日期:2014-05-19  浏览次数:20533 次

为什么两个insert的结果不同呢?
一样的数据,为什么#temp是插在前面?
create   table   #t   (a   int)
insert   #t   select   2
union   all   select   5
union   all   select   3
union   all   select   6
union   all   select   1
union   all   select   4

select   *   into   #temp   from   #t  
select   *   from   #temp

insert   into   #temp   select   *   from   #t   order   by   a
insert   into   #t   select   *   from   #t   order   by   a

select   *   from   #temp
select   *   from   #t

drop   table   #t
drop   table   #temp

所影响的行数为   6   行)


(所影响的行数为   6   行)

a                      
-----------  
2
5
3
6
1
4

(所影响的行数为   6   行)


(所影响的行数为   6   行)


(所影响的行数为   6   行)

a                      
-----------  
1
2
3
4
5
6
2
5
3
6
1
4

(所影响的行数为   12   行)

a                      
-----------  
2
5
3
6
1
4
1
2
3
4
5
6

(所影响的行数为   12   行)

------解决方案--------------------

to CathySun118(斯年) 对于select 的变量赋值加order by 这个我知道不用你解释,我是在说select into 的排序,看到很多人说select into 排序无用而要写成select into from (select .. order by ) t这样的形式,但我这的SQLSever执行的时候都不需要这样写,所以我才要问啊

======================================================
对于这个, 我认为, 排序后的数据在插入时, 处理的顺序是按照排序后的数据, 只是在实际存储到数据页时, 由于数据文件中保留的空间位置的问题, 导致数据在数据文件中的位置(数据页的逻辑位置)无法保障顺序. 而检索数据是按数据页的顺序来检索的, 所以检索结果的顺序受数据页位置的影响, 从而出现了楼主看到的现象.

------解决方案--------------------
TO zjcxc(邹建) ( ) 信誉:673 Blog

首先,char(8000)确实不会跨页,这个是我搞错了。

其次,我测试了 char(8000)的情况,结果很惊人,SELECT INTO 的原始数据前会留 N 个空白页,而不是一个空白页。N可能是1,页可能是593,可能是10,可能是任何数,根据情况不同会不同

再次,用create table建成的表,其select的顺序也和insert的顺序没有关系,从多次测试的结果看,insert顺序很可能是随机。(你说得到的顺序是一致的,那恭喜你,你真幸运,我测试了4次,得到了4种顺序。)

最后,我的讨论都是基于一个假设,select的顺序和页存储的顺序是一致的,但是到底什么才是页存储的顺序呢?SELECT 又是按照什么样的顺序来轮询数据页的?看来只有知道MSSQL的存储设计原理才能回答这个问题了。(貌似如果可以获得这个原理的话,我们就可以破解MSSQL数据库文件了。)

下面是我的测试sql:

--create table 建表方式。
create table t1 (a char(8000))

insert t1 values ( '1 ')

--select into 建表方式。
select 1 as a into t2

declare @i int
set @i = 2
while @i < 1000
begin
insert t1 values (convert(varchar(10),@i))
insert t2 values (convert(varchar(10),@i))
set @i = @i + 1
end

select * from t1
select * from t2

drop table t1
drop table t2
------解决方案--------------------
同意

zjcxc(邹建) ( ) 信誉:673 Blog 2007-3-20 12:51:21 得分: 0


插入顺序决定存储顺序(没有聚集索引的情况下)

这个不全对, 应该是数据实际存储在数据页上的顺序

楼主或者楼上可以把int变成 char(8000) 去测试.


"建表方式不同导致的 ", 这点就不同意了,不过没有证据,说说自己的理解:

1、没有聚集索引的情况下,没有order by查询出来的一定是存储的次序。
2、存储的次序应该决定于数据实际存储在数据页上的顺序,注意这里的数据页指的是硬盘上