【问题标题】:Removing clustered index scan even if selected columns are part of index即使选定的列是索引的一部分,也删除聚集索引扫描
【发布时间】:2015-03-28 23:17:13
【问题描述】:

以下脚本是我所面临情况的简化示例 -

CREATE TABLE #tmp(pk bigint IDENTITY(1,1),id bigint, dt datetime)


DECLARE @X BIGINT=1
WHILE (@X<9223372036854775807)
BEGIN
  INSERT INTO #tmp VALUES (@X,GETDATE())
  SET @x=@x+1
END

CREATE INDEX idx on #tmp(id,dt)

SELECT id,max(dt) from #tmp  GROUP BY id 

这个SP的执行计划是扫描创建的索引,如何移动到SEEK?

提前致谢!

【问题讨论】:

  • 您的查询正在从表中提取每一行。即将进行扫描。
  • 如果 id 与该索引重复,您可能会进行松散的索引扫描,但由于 id 是主键,您会被索引扫描卡住。MAX 和 GROUP BY 也是多余的。也许您的意思是 @ 987654322@
  • 如果您要遍历表的每一行,为什么还要寻找?,这里扫描是更好的方法
  • 出于好奇,有人尝试将其一直运行到 9223372036854775807 吗?这需要很长时间,不是吗?
  • 9223372036854775807 太过分了,我只是想制作足够大的数据库。预计会进行扫描,但想看看是否有更好的方法来处理这个问题。

标签: sql-server performance query-optimization non-clustered-index


【解决方案1】:
CREATE TABLE #tmp
  (
     pk BIGINT IDENTITY(1, 1),
     id BIGINT,
     dt DATETIME
  )

DECLARE @X BIGINT=1

WHILE ( @X < 9223372036854775807 )
  BEGIN
      INSERT INTO #tmp
      VALUES      (@X,GETDATE())

      SET @x=@x + 1
  END

CREATE INDEX idx
  ON #tmp(id, dt)   /*<-- New*/

SELECT id,
       max(dt)
FROM   #tmp
GROUP  BY id 

【讨论】:

  • 请添加一些解释性文字。
猜你喜欢
  • 2019-08-26
  • 1970-01-01
  • 1970-01-01
  • 2015-01-27
  • 2014-12-18
  • 1970-01-01
  • 1970-01-01
  • 2023-03-14
  • 1970-01-01
相关资源
最近更新 更多