2009-08-10 62 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,那麼您可以先查找電子郵件地址,然後查找匹配的姓名。