本帖最后由 ache2012 于 2015-02-08 10:16:52 编辑

解决方案 »

  1.   

    利用主键的排序,分区,筛选一行。
    select *    --*具体的字段
    from 
    (
         select row_number() over(partition by ID1,ID2,ID3 order by ID1 ASC) AS RN,
                      *      --具体的字段
    ) as T
    where RN=1
      

  2.   


    我觉得可以试试这样:操作之前 先备份一下数据库。select distinct id1,id2,id3... into 新的表
    from 表然后:exec sp_rename 'dbo.原表','原表bak'exec sp_rename 'dbo.新的表','原表'
      

  3.   


    直接SELECT * 不是一个好习惯,并且对覆盖索引不好利用,但你可以按照你的具体情况用。
      

  4.   


    直接SELECT * 不是一个好习惯,并且对覆盖索引不好利用,但你可以按照你的具体情况用。
    具体代码要怎么写?兄弟我对sql是小白,能麻烦你写个例子吗?
    成功了送[100分]+送一个月万网空间【已买】或者分你自用的vps【当然是子空间】
      

  5.   


    就是在你访问频率最高,时间最长的字段上,根据查询条件来建立索引。
    如: 
    select id1,id2,id3 ,orderdate
    from Tb
    where id=1001 and orderdate>'2014-02-05'
    这时可以建立覆盖索引:
    create nonclustered index index_name_cover_tb on Tb(id1)
    include(id2,id3,orderdate)
    索引是很一门有深度而优雅的知识,建议你找下书深入学习一下,如果你喜欢数据库;
    如果你不喜欢,看看也无妨。
      

  6.   

    上面的代码应该写为:
    select *    --*具体的字段
    from 
    (
         select row_number() over(partition by ID1,ID2,ID3 order by ID1 ASC) AS RN,
                      *      --具体的字段
         from [dbo].[odre](nolock)
    ) as T
    where RN=1
      

  7.   


    就是在你访问频率最高,时间最长的字段上,根据查询条件来建立索引。
    如: 
    select id1,id2,id3 ,orderdate
    from Tb
    where id=1001 and orderdate>'2014-02-05'
    这时可以建立覆盖索引:
    create nonclustered index index_name_cover_tb on Tb(id1)
    include(id2,id3,orderdate)
    索引是很一门有深度而优雅的知识,建议你找下书深入学习一下,如果你喜欢数据库;
    如果你不喜欢,看看也无妨。暂时关闭维护了,没有开放查询,对sql,asp,php,还是很有兴趣的,看得懂一点点而已
    平时没时间来做这些,更别说看资料了。
    能否解释下这几个例子的意思?【好吧,是我要求太高了】
      

  8.   

    select *    --*具体的字段
    from 
    (
         select row_number() over(partition by 列1,列2,列3 order by 主键 ASC) AS RN,
                      *      --*具体的字段--到这里是去重复?
         from [dbo].[odre](nolock)    ---*这里是重新生成覆盖索引吗?
    ) as T
    where RN=1    --*不知道我理解的对不对
      

  9.   

    row_number() over(partition by 列1,列2,列3 order by 主键 ASC) AS RN
    这里主要使用了这个排序函数;
    partition by 列1,列2,列3 order by 主键 ASC ;意思是根据 列1,列2,列3 来分组,生成的序号按照
    主键 ASC 升序排序;
    然后 where RN=1 的意思是 在所有分组中,每组取第一行,达到去重复的目的。
      

  10.   


    非常感谢你,我回去备份一下按你的代码来做,这只是改动原表,在表里直接删除重复的吗?
       from [dbo].[odre](nolock)    ---*这里是重新生成覆盖索引吗?
    ) as T
    数据比较庞大,不敢贸然下手,成功了我会兑现我的诺言,不知兄弟看的上看不上,
    发了私信给你我的vps挂的一个站。
      

  11.   

    感谢你的好意。
    我上面的写法只是达到筛选不重复的行,查询出来。
    from [dbo].[odre](nolock)  --这里不是重新生成覆盖索引,是查询数据的基本语法。
    若你的重复数据需要去除,可以这样写:
    ;WITH CTE AS(
    select row_number() over(partition by ID1,ID2,ID3 order by ID1 ASC) AS RN,
                      *      --具体的字段
         from [dbo].[odre](nolock)
    )
    DELETE  FROM CTE
    WHERE RN<>1
      

  12.   

    设计不当搞出一堆烂数据,根本没法做出有效的查询。
    建议重新处理一下,切分成两张表:
    用email或name作为唯一标识,比如主表(id,email)、子表(主表id,id,其它字段),子表以(主表id,id)为主键。
    这样一边切分记录,一边可以在插入子表前在主表id这个小范围内去重复。
    以后新来数据也是先判断非重复后再插入。
      

  13.   

    这么大的数据查不出来吧,我拿1000个做实验先,不知道电脑吃得消吃不消6e数据,这个肯定需要一段时间的,6亿条数据
    我之前用dbcc dbreindex('new.dbo.sgk','',90)重新生成索引的,基本上是3-5个小时
    前面删除重复完了能用这句来重新生成索引吗
      

  14.   

    这么大的数据查不出来吧,我拿1000个做实验先,不知道电脑吃得消吃不消6e数据,这个肯定需要一段时间的,6亿条数据
    我之前用dbcc dbreindex('new.dbo.sgk','',90)重新生成索引的,基本上是3-5个小时
    前面删除重复完了能用这句来重新生成索引吗可以的,这种是老的方式,也可以:alter index 索引名称 on 你的表名称
    rebuild
     
      

  15.   

    这么大的数据查不出来吧,我拿1000个做实验先,不知道电脑吃得消吃不消6e数据,这个肯定需要一段时间的,6亿条数据
    我之前用dbcc dbreindex('new.dbo.sgk','',90)重新生成索引的,基本上是3-5个小时
    前面删除重复完了能用这句来重新生成索引吗可以的,这种是老的方式,也可以:alter index 索引名称 on 你的表名称
    rebuild
     

    alter index 原索引名称 on 表名称
    rebuild 
    是这样比老的那种方式效率更高吗?是会覆盖原来的索引吗吗感恩
      

  16.   

    这么大的数据查不出来吧,我拿1000个做实验先,不知道电脑吃得消吃不消6e数据,这个肯定需要一段时间的,6亿条数据
    我之前用dbcc dbreindex('new.dbo.sgk','',90)重新生成索引的,基本上是3-5个小时
    前面删除重复完了能用这句来重新生成索引吗可以的,这种是老的方式,也可以:alter index 索引名称 on 你的表名称
    rebuild
     

    alter index 原索引名称 on 表名称
    rebuild 
    是这样比老的那种方式效率更高吗?是会覆盖原来的索引吗吗感恩其实就是 完全 重新建索引,其实就是新的写法,基本原理和过程是一样的。
      

  17.   

    这么大的数据查不出来吧,我拿1000个做实验先,不知道电脑吃得消吃不消6e数据,这个肯定需要一段时间的,6亿条数据
    我之前用dbcc dbreindex('new.dbo.sgk','',90)重新生成索引的,基本上是3-5个小时
    前面删除重复完了能用这句来重新生成索引吗可以的,这种是老的方式,也可以:alter index 索引名称 on 你的表名称
    rebuild
     

    alter index 原索引名称 on 表名称
    rebuild 
    是这样比老的那种方式效率更高吗?是会覆盖原来的索引吗吗感恩其实就是 完全 重新建索引,其实就是新的写法,基本原理和过程是一样的。以后加入新的数据,会自动生成索引吗?还是需要手动重新全部生成新的索引
      

  18.   

    这么大的数据查不出来吧,我拿1000个做实验先,不知道电脑吃得消吃不消6e数据,这个肯定需要一段时间的,6亿条数据
    我之前用dbcc dbreindex('new.dbo.sgk','',90)重新生成索引的,基本上是3-5个小时
    前面删除重复完了能用这句来重新生成索引吗可以的,这种是老的方式,也可以:alter index 索引名称 on 你的表名称
    rebuild
     

    alter index 原索引名称 on 表名称
    rebuild 
    是这样比老的那种方式效率更高吗?是会覆盖原来的索引吗吗感恩其实就是 完全 重新建索引,其实就是新的写法,基本原理和过程是一样的。以后加入新的数据,会自动生成索引吗?还是需要手动重新全部生成新的索引这个还是需要定期 重建索引,也就是需要 定期维护的。
      

  19.   

    日志也要占空间的,另外定义里面的WITH (FILLFACTOR=90)代表数据页只占满90%,一般是不要去改动也就是数据页存满8K。还有你大量使用Unicode类型的列,存储空间翻倍。这些都导致你的数据库体积很大。如果你的数据库可以短暂停机,而且空间足够,可以尝试下面方式一次性处理,不过后续的数据你需要做判断再处理:
    1、select distinct * into #t from odre --这里的*根据你的实际要求而定,我假设你全表的列都完全重复。至于那个ID就先不管了,除非你的ID是有意义的,另外text列,都已经是2005了,换成nvarchar(max)/varchar(max)这类吧。
    2、truncate table odre
    3、insert into order(写完你的列,要和select的一一对应) select xxxxx from #t
    这样可以一次性去除所有列均相同的数据,但是是一次性的。做之前先备份,最起码备份这个表。
      

  20.   

    数据量较大,直接整表处理对数据库日志冲击太大不合适,建议分批处理(如每次处理5000行),
    如下例子供参考.declare @minid int,@maxid intselect @minid=min(id),
           @maxid=max(id)
     from odrewhile(@minid<[email protected])
    begin
     -- 删除重复的记录,只保留id最小的那条记录.
     delete a
      from odre a
      inner join
      (select [重复值的字段列表],min(id) 'id'
       from odre 
       where id between @minid and @minid+5000
       group by [重复值的字段列表]
       having count(1)>1) b on a.[重复值的字段列表]=b.[重复值的字段列表] and a.id<>b.id
      where a.id between @minid and @minid+5000 select @[email protected]+5001
    end