【问题标题】:SQL Server index usage questionSQL Server 索引使用问题
【发布时间】:2009-08-10 05:05:00
【问题描述】:

假设如下:

/*

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

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

【问题讨论】:

    标签: sql-server performance query-optimization


    【解决方案1】:

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

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

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

    【讨论】:

    • 很好,是的,索引中从未使用过的“email”列的包含使它对这个查询毫无用处
    • 我有另一个使用电子邮件列的查询。我将它添加到该索引中,希望两个查询都可以使用它,而不是拥有 2 个大索引。我应该只创建两个索引吗?
    • 根据问题中的信息,我将在 (firstname,lastname) 和 (email) 上创建两个索引。这些索引应该几乎唯一地标识一行。
    【解决方案2】:

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

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

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

    【讨论】:

      【解决方案3】:

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

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

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

      我相信这会对您规划索引时有所帮助。

      【讨论】:

        猜你喜欢
        • 2010-11-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-09-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多