如何正确创建索引

时间:2009-03-06 04:33:25

标签: sql sql-server indexing

我在SQL Server 2005中有以下非常大的表:

create table Blah 
(
  FirstName varchar(30),
  Rank int,
  Position int,
  ...
)

我将对其运行以下查询:

declare @PassedInFirstName varchar(30)
set @PassedInFirstName = 'SomeName'

select TOP 1 Position
from Blah
where FirstName = @PassedInFirstName
order by Rank DESC

我正在设置以下索引:

CREATE INDEX IX_Blah ON Blah (FirstName, Rank)

鉴于我是通过Rank DESC订购的,我是否应该将索引更改为按降序排列Rank:

CREATE INDEX IX_Blah ON Blah (FirstName ASC, Rank DESC)

或者没关系?

感谢。

3 个答案:

答案 0 :(得分:3)

如果WHERE返回许多行,那么应该会受益。

通过在INDEX中使用DESC来匹配ORDER BY,我看到逻辑IO减少了50%的结果

此外,将查询更改为覆盖:

SQL 2005 +:

CREATE INDEX IX_Blah ON Blah (FirstName, Rank DESC) INCLUDE (Position)

SQL 2000,SQL 7:

CREATE INDEX IX_Blah ON Blah (FirstName, Rank DESC, Position)

答案 1 :(得分:2)

在索引中添加Rank作为降序值只是一个小改动。 Sql Server可以可能反转使用的排序,或者在这种情况下,很容易迭代到列表中的最后一项。

位置是您的主键吗?索引由索引列,主键和可选包含的列构成。如果Position不是您的主键,那么您当前正在索引中查找主键,然后使用主索引查找结果以寻找位置值。尝试将Position值添加为包含列,您应该能够仅基于一个索引执行查询,不会使用其他索引。

CREATE INDEX IX_Blah ON Blah (FirstName, Rank DESC) INCLUDE (Position)

别忘了查看您的查询计划,他们可以告诉您是否缺少任何索引(假设是Sql Server 2008),使用了哪些索引等等。

答案 2 :(得分:0)

我在上一篇文章中搞砸了身份验证,这是我的注册用户。

索引基于您选择的列和主键。您基本上存储了一个hashmap,其中键(FirstName,Rank)解析为您的Id(假设您的主键是Id)。然后使用此Id读取位置值。

我的主张是将Position值作为包含列包含在索引中。这将允许您从索引中读取数据,避免第二次查找。