none
建索引时通常的排序方式是顺序,如果设置成倒叙会有什么样的影响吗? RRS feed

  • 问题

  • 如题,例如文章表主键id是自增长的,我通常要按照id倒叙排列取数据,而id的索引上顺序排的;这样对查询性能有多大影响?

    再有假如我设置了该列上的索引按照倒叙排,对插入的性能会有影响吗,会有多大影响。

     

    谢谢。

    2008年5月8日 0:57

答案

全部回复

  • 合理的创建索引会带来很大的性能上面的提高

    你可以参考:

    http://technet.microsoft.com/zh-cn/library/ms181154.aspx

    http://technet.microsoft.com/zh-cn/library/ms191195.aspx

    你根据应用的情况来定义排序顺序肯定会有好处的.
    2008年5月8日 3:40
  • 我做了一个试验,性能上确实有差别,不过实际的执行计划却是一模一样的,sql server版本是2005。

    Code Snippet

    if object_id('test_indexorder','U') is not null
    begin
     truncate table test_indexorder
     drop table test_indexorder
    end
    go
    create table test_indexorder
    (
     id int identity(1,1) not null,
     name varchar(20) not null,
     content varchar(50) not null,
     co1 varchar(50),
     co2 varchar(50),
     co3 varchar(50),
     co4 varchar(50),
     co5 varchar(50),
     constraint pk_testorder primary key clustered(
      id desc
     )
    )
    go
    --insert 1000000 条数据
    set nocount on;
    declare @t datetime;
    set @t = getdate();

    DECLARE @cn int;
    set @cn = 1000000;
    while(@cn > 0)
    begin
     insert into test_indexorder(name,content,co1,co2,co3,co4,co5) 
     VALUES(
      'name' + cast(@cn as varchar(10)),
      cast(newid() as varchar(50)),
      cast(newid() as varchar(50)),
      cast(newid() as varchar(50)),
      cast(newid() as varchar(50)),
      cast(newid() as varchar(50)),
      cast(newid() as varchar(50)));
     set @cn = @cn -1;
    end
    print '插入时间(毫秒):';
    print datediff(millisecond,@t,getdate());
    set nocount off;
    go
    set nocount on;
    declare @t datetime;
    set @t = getdate();
    with t_rn as (
     select *,rn = ROW_NUMBER() OVER (ORDER BY id desc) FROM test_indexorder
    )
    SELECT id,name,content,co1,co2,co3,co4,co5 from t_rn WHERE rn between 19007 and 19057;
    print '查询时间(毫秒)'
    print datediff(millisecond,@t,getdate())

    set @t = getdate();
    with t_rn as (
     select *,rn = ROW_NUMBER() OVER (ORDER BY id asc) FROM test_indexorder
    )
    SELECT id,name,content,co1,co2,co3,co4,co5 from t_rn WHERE rn between 17007 and 17057;
    print '查询时间(毫秒)'
    print datediff(millisecond,@t,getdate())
    set nocount off;

     

     

    如下执行计划:
    http://www.cnblogs.com/images/cnblogs_com/yukaizhao/133619/o_plan_exec.jpg

    2008年5月9日 2:02
  • 索引是倒序,当查询也是倒序时,可以节省服务器上排序的时间,可以提高一定的性能。
    索引是顺序还是倒序,对插入的性能没有影响。

    2008年5月9日 7:26
  • 谢谢两位的答复。

     

    2008年5月9日 7:29
  •  

    没有任何影响。

    在索引树内是个双向链表,从左边开始扫描还是从右边开始扫描,IO,结果都是一样。

     

    理论上来说索引按照倒序排,对插入会有影响

    因为从数据在页面的逻辑排序上来说,如果有新增数据行,会使得数据往上插而导致也拆分??我比较怀疑,但是我觉得对应的SLOTID对解决这个插入的性能问题,我觉得不会有问题,等我测试结果,看看到底有没有问题。

     

    2008年5月9日 14:27
  • Will cause page split when you add value in any page that is full or near full, no matter how you order pages.

    2008年5月9日 16:29
  •  向翔 写:

     

    没有任何影响。

    在索引树内是个双向链表,从左边开始扫描还是从右边开始扫描,IO,结果都是一样。

     

    理论上来说索引按照倒序排,对插入会有影响

    因为从数据在页面的逻辑排序上来说,如果有新增数据行,会使得数据往上插而导致也拆分??我比较怀疑,但是我觉得对应的SLOTID对解决这个插入的性能问题,我觉得不会有问题,等我测试结果,看看到底有没有问题。

     

     

    同意。理论上说查询和修改都没有影响如果是单列的clustered索引。我也实际试了一下以上查询,得到的结果也是没有区别。我能想到的是,当建立两列或多列组合索引时可能会不同。比如:A列,B列都同时建为组合索引,建索引时都为升序排列,当查询时,A,B都为升序应该比A为升序B为降序要快。
    2008年5月12日 4:37
  • 这个插入当然指的是在表末尾插入的吧,不然在页中间的插入也谈性能,那也太不实际了
    2008年5月13日 8:38
  • How can you control where to put inserted rows if table has clustered index on column other than identity?

    2008年5月13日 14:36