假设如下:
/*
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 = ''
为什么第二个索引会导致索引扫描,而第一个索引会导致索引搜索?键的顺序有什么不同?
答案 0 :(得分:5)
第二个索引以电子邮件字段开头,但您没有过滤电子邮件。这使得索引无用。
索引通常为b-tree,允许您执行binary search。 b树按其索引字段排序。因此,如果您知道第一个字段,则可以快速查找。在第一个字段的相同值内,您可以非常快速地查找第二个字段。
这就像一本按姓氏排序的电话簿。您无法使用它来搜索特定的电话号码。
答案 1 :(得分:0)
应用“电话簿”类比可能有助于理解。
第一个索引是一个'电话簿',按FirstName排序,然后是姓氏,依此类推。 如果你被要求在这本电话簿中查找克里斯,那么你可以找到索引所列的所有克里斯。
在第二个索引中,是一个电话簿按“电话号码”排序(或电子邮件一样容易),然后是名字,然后是姓氏等。 如果您要求使用此电话簿查找带有Chris姓名的列表,那么您的运气不好,电话簿就不会那样排序!当然,如果您被要求查找电子邮件地址example@example.com并命名为Chris,那么您可以先找到该电子邮件地址,然后查找匹配的名称。
答案 2 :(得分:0)
在索引“索引中的列排序”的情况下,“where子句中的列排序”将会遇到很多。你可以参考以下链接:
http://ashishkhandelwal.arkutil.com/sql-server/quick-and-short-database-indexes/
•使用索引的最佳实践 •如何获得最佳性能表单索引 •聚集索引注意事项 •非聚集索引注意事项
我确信这会在规划索引时帮助您。