【问题标题】:Correct order of columns in an index in SQL ServerSQL Server 中索引中列的正确顺序
【发布时间】:2013-12-18 16:23:41
【问题描述】:

我的查询看起来像:

select top 1
      a
    , b
    , c
from table
where x = 1
and   y = 2
and   z > getdate()
order by 
      b desc
    , c desc

还有一个类似的索引:

create index idx_ on table
(
     x
   , y
   , z
   , b
   , c
)
include (a)

我的问题是过滤后我留下了大约 600 万条记录。而且 SQL Server 也不会根据索引进行排序,因此该查询的时间非常长。

计划如下:

select (0%) <- TOP N SORT (94%) <= INDEX SEEK (6%)

如何为索引选择列,或者以这种方式更改选择,以便我可以从索引中受益。

此外,选择必须能够适合外部应用,这是不将其分解成碎片的主要原因。 x 字段是外部选择链接的字段。

作为问题的更新,整个 sql 看起来像:

select 
*
from #tmp_xs xs
outer apply 
  (select top 1
        a
      , b
      , c
  from table
  where x = xs.rel_x
  and   y = 2
  and   z > getdate()
  order by 
        b desc
      , c desc) xs_res

出于某种原因,上面的查询sql server 将只使用过滤索引。如果将内部查询放在内联函数中,则结果是相似的。如果我不把它放在一个内联函数中,两个索引都可以工作并且查询非常快。

【问题讨论】:

  • 该索引可能用于选择过程 - 因为它包含正在查询的 x, y, z。但是它不能用于排序,因为排序列bc 不是该索引中最左边的列!我建议您在(x, y, z) 上创建索引以供选择,并在(b, c) 上创建第二个单独的索引以供订购
  • 谢谢,它工作得很好..虽然我不知道如何将它标记为正确..
  • 问题是,为什么放在outer apply里面之后,又回到了旧的plan(就像上面那个,不使用第二个索引)

标签: sql sql-server-2008 indexing


【解决方案1】:

您已经拥有的索引可能会用于选择过程 - 因为其中有 x, y, z 作为最左侧的列被查询。

但它不能用于排序,因为排序列 bc 不是该索引中最左侧的列。

我建议您在 (x, y, z) 上创建一个索引以供选择,并在 (b, c) 上创建第二个单独的索引以对结果进行排序。

【讨论】:

  • 这是对我的问题的一个很好的答案.. 但是.. 为什么当放置在外部应用中时,它不会使用第二个索引?
  • @DumitrescuBogdan:您没有显示您所指的 外部应用 - 所以我真的不能说问题是什么......
  • 好的,我更新了帖子..我修复了它但是将查询放在非内联表函数中..但我不喜欢我不知道发生了什么。
【解决方案2】:

在 SSMS (SQL Server Management Studio) 中运行您的查询并要求它生成一个查询计划。它提供了有关索引的提示,这些提示会有所帮助,实际上它非常擅长。除此之外,@marc_s 听起来很明智,但我还是会先在 SSMS 中尝试一下。

【讨论】:

  • Marks 的答案正是我想要的。实际上是我的错误,因为我有第二个索引,但我使用的提示只有我显示的索引。原帖中的 QP 来自 SSMS。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-08-05
  • 1970-01-01
  • 2010-09-25
  • 2014-01-09
  • 2014-01-06
  • 2015-04-13
相关资源
最近更新 更多