2009-03-06 34 views
2

我已经在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) 

考虑到我的排名倒序它,我应该改变该指数下降的方式进行排序:

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

或者没关系?

谢谢。

回答

3

如果WHERE返回。如果应受益许多行。

我已经看到了结果,其中逻辑IO减少了50%,通过在索引使用DESC以匹配ORDER BY

此外,查询更改为覆盖:

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) 
+0

+1为覆盖件 – AngryHacker 2009-03-06 05:49:58

2

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

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

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

不要忘记检查你的查询计划,他们可以告诉你,如果你没有任何索引(假设SQL Server 2008中),使用什么索引等

+0

这里没有涉及主键,也没有任何列是唯一的。 – AngryHacker 2009-03-06 05:51:15

0

我搞砸了验证我的前面p ost,这是我的注册用户。

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

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