2

假设如下:

/*

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 = ''

为什么第二个索引会导致索引扫描,而第一个索引会导致索引查找?键的顺序有什么不同?

4

3 回答 3

5

第二个索引从电子邮件字段开始,但您没有过滤电子邮件。这使得索引毫无用处。

索引通常是允许您进行二进制搜索的b 树。b 树按其索引字段排序。因此,如果您知道第一个字段,则可以快速查找。在第一个字段的相同值内,您可以非常快速地查找第二个字段。

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

于 2009-08-10T05:19:47.493 回答
0

应用“电话簿”类比可能有助于理解。

第一个索引是按名字排序的“电话簿”,然后是姓氏,依此类推。如果您要求在此电话簿中查找 Chris,那么您可以通过索引找到一起列出的所有 Chris。

在第二个索引中,是按“电话号码”(或电子邮件也很容易)排序的电话簿,然后是名字,然后是姓氏,依此类推。如果您要求使用此电话簿查找名字为 Chris 的列表,那么您很不幸电话簿不是这样排序的!当然,如果要求您查找电子邮件地址 example@example.com 和姓名 Chris,那么您可以先查找电子邮件地址,然后查找匹配的姓名。

于 2009-08-10T08:39:15.050 回答
0

在索引“索引中的列排序”的情况下,“where 子句中的列排序”会非常重要。您可以参考以下链接:

http://ashishhandelwal.arkutil.com/sql-server/quick-and-short-database-indexes/

•使用索引的最佳实践•如何获得最佳性能的索引•聚集索引注意事项•非聚集索引注意事项

我相信这会在您规划索引时帮助您。

于 2012-06-26T06:31:07.213 回答