none
sqlserver额外排序问题 RRS feed

  • 问题

  • 正式环境遇到一个问题,

    slect top 11 * from t1 where a>='2017-10-1' and a<'2017-10-2' order by a

    a字段为分区列也为聚集列(聚集列就a一个字段),并且上述查询当中,没有夸分区(在同一个分区里面)

    查看执行计划,非常奇怪,的确走的聚集索引查找,但是有额外的排序操作,导致资源消耗非常严重,按道理说:既然走了聚集索引查找,又是order by聚集索引首字段,不应该有排序开销才对,为何呢?


    2017年11月5日 6:56

答案

  • 可能是优化器犯傻了

    前阵子我提过一个Max()“问题“,SQL 2016/2017优化器犯傻,但2008则正确

    试下

    select * From (select top 11 * from t1 where a>='2017-10-1' order by a) t where a<'2017-10-2' order by a

    **不清楚版本,未作实测


    SQL Server 2016 ~ 2000 性能优化、方案设计 QQ:315054403 田园嘉兴

    • 已标记为答案 wanyongwy 2017年11月23日 13:25
    2017年11月5日 12:43

全部回复

  • 可能是优化器犯傻了

    前阵子我提过一个Max()“问题“,SQL 2016/2017优化器犯傻,但2008则正确

    试下

    select * From (select top 11 * from t1 where a>='2017-10-1' order by a) t where a<'2017-10-2' order by a

    **不清楚版本,未作实测


    SQL Server 2016 ~ 2000 性能优化、方案设计 QQ:315054403 田园嘉兴

    • 已标记为答案 wanyongwy 2017年11月23日 13:25
    2017年11月5日 12:43
  • 如果a是聚集索引,结果就应该是你要的,为啥还要执行order by a?你这个既然是有问题,估计是在查找之前排序了?感觉sql不会这么傻,是不是有什么其他原因你没注意到?


    family as water

    2017年11月6日 0:47
  • 额外排序做是用什么排序的?

    建议你贴出表结构和执行计划,并给出你用的版本

    2017年11月6日 1:02
  • SQLSERVER2008 R2版本,i_time为聚集索引,并且只有time一个字段

    2017年11月6日 2:47
  • 按照你的方法试了一下  ,还是不行
    2017年11月6日 2:47
  • Hi wanyongwy,

        您好!能否测试这样一种情况,将你表中的数据移到另外一张表(包括表结构),然后将查询的执行计划反馈给我们,具体操作方式如下:

    --生成新表
    select top 1 *  into new_table_name from Your_table
    
    delete from new_table_name
    --创建聚集索引
    create CLUSTERED INDEX IX_new_table_name_time
    ON new_table_name([time])
    
    --适当加一下条件,插入部分数据到新表
    insert into new_table_name
    select * from Your_table
    
    
    --执行完后,反馈一下执行计划
    select  top 11 * from new_table_name
    where [time]>='2017-10-18' and [time]<='2017-10-19'
    order by [time] asc
    
    
    drop table new_table_name

    Best Regards,

    Will


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    2017年11月6日 4:47
  • 你是按天分区的吗?是否因为你用了闭区间导致查询跨分区?

    看看你的执行计划中,用到的分区数。


    想不想时已是想,不如不想都不想。

    2017年11月6日 5:48
    版主
  • 没有跨区,都在同一个区里面
    2017年11月6日 5:53
  • 生成一个新表,在新表里面查询时没有问题的,不会有额外的排序操作

    2017年11月6日 6:00
  • Hi wanyongwy,

        谢谢您的反馈,那说明您的优化器是没有问题的。唯一的可能性就是你的原始表的聚集索引列有索引碎片,估计要重建索引,相关指导,请参见这篇文章:

    Reorganize and Rebuild Indexes

    Best Regards,

    Will


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    2017年11月6日 6:09
  • 谢谢 ,但是重建了的,重建后依然这样
    2017年11月6日 7:42
  • seect * 改成 seect a, 只取主键列的执行计划正常么?

    你的新表测试,新表也是分区表? 有相同的数据?

    2017年11月6日 8:22
  • 谢谢 ,但是重建了的,重建后依然这样

    Hi wanyongwy,

          忘记这样一个情况,不管分区索引被创建还是被重建,统计不会被自动创建去扫描预估表中所有记录,相反,查询优化器使用默认的采样算法生成统计信息,你可以按照我之前的测试样例,创建一个新的分区表,然后往里面放数据,是不是这么回事?

    该情况的测试,请见这篇文章:Partitioned Tables and Indexes(具体内容在标题"Behavior Changes in Statistics Computation During Partitioned Index Operations"下)

    Best Regards,

    Will


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    2017年11月6日 9:12
  • 新表也是分区表,数据只是比实际表的数据少一些而已,分区函数 分区方案都是相同的

    如果只取主键列,会走另外的索引,看不出效果

    但是,如果在表后面加上强制索引(强制走聚集索引),就是正常的,不会有额外的排序,但是:

    当没有加强制走聚集索引的时候,最后从执行计划看来,其也是走的聚集索引查找,只是要额外排序,真是奇怪



    2017年11月6日 13:13
  • 试试新表也使用相同的数据的情况

    对于只主争冠的情况,会使用另外的索引,这个索引也是主键列 time? 如果是的话,似乎不正常,如果普通索引也是 time 列,你用 select time from tb where time ... order by time,那么只需要索引就可以出数据,会再走聚集索引说不过去

    所以还是希望你给表结构脚本

    2017年11月7日 1:19