2009-08-10 99 views
2

假设如下:的SQL Server索引的使用问题

/* 

drop index ix_vouchers_nacsz on dbo.vouchers; 
drop index ix_vouchers_nacsz2 on dbo.vouchers; 

create index ix_vouchers_nacsz on dbo.Vouchers(
    FirstName, LastName, 
    Address, Address2, City, 
    State, Zip, Email 
); 

create index ix_vouchers_nacsz2 on dbo.Vouchers(
    Email, FirstName, LastName, 
    Address, Address2, City, 
    State, Zip 
); 

*/ 

select count(firstname) from vouchers 
    with (index(ix_vouchers_nacsz)) 
where 
    firstname = 'chris' and 
    lastname = '' and 
    address = '' and 
    address2 = '' and 
    city = '' and 
    state = '' and 
    zip = '' 

select count(firstname) from vouchers 
    with (index(ix_vouchers_nacsz2)) 
where 
    firstname = 'chris' and 
    lastname = '' and 
    address = '' and 
    address2 = '' and 
    city = '' and 
    state = '' and 
    zip = '' 

为什么第二索引的结果索引扫描,而在指数第一的成绩求?密钥的排序有什么不同?

回答

5

第二个索引以电子邮件字段开头,但您不在电子邮件上进行过滤。这使索引无用。

索引通常是b-tree,它允许您执行binary search。 B树按其索引字段排序。所以如果你知道第一个领域,你可以快速查找它。在第一个字段的相同值内,您可以快速查找第二个字段。

这就像一个按姓氏排序的电话簿。您无法使用它来搜索特定的电话号码。

+0

好的一点,是的,在索引中包含“电子邮件”列是从来没有使用的呈现它对这个查询 – 2009-08-10 05:38:37

+0

我没有使用电子邮件列另一个查询。我将它添加到这个索引中,希望这两个查询都可以使用它,而不是有两个大的索引。我应该创建两个索引吗? – Chris 2009-08-10 05:52:41

+1

根据问题中的信息,我会在(名字,姓氏)和(电子邮件)上创建两个索引。这些索引几乎应该唯一标识一行。 – Andomar 2009-08-10 06:12:07

0

应用'电话簿'比喻可能有助于理解。

第一个索引是按姓氏排序的'电话簿',然后是Last Name等。 如果你要求在这本电话簿中查找Chris,那么你可以找到所有Chris列在一起的索引。

在第二个索引中,是一个按'电话号码'(或电子邮件就像轻松),然后是名字,然后是姓氏等排序的电话簿。 如果您要求使用此电话簿查找Ch​​ris的名字,您的运气不好,电话簿不会按这种方式排序!当然,如果您被要求查找电子邮件地址[email protected]并命名Chris,那么您可以先查找电子邮件地址,然后查找匹配的姓名。