繁体   English   中英

在非聚集索引中,第二,第三,第四…列如何排序?

[英]In a nonclustered index, how are the second, third, fourth … columns sorted?

我有关于SQL Server索引的问题,最近一直困扰着我。

想象一个这样的表:

CREATE TABLE TelephoneBook (
    FirstName nvarchar(50), 
    LastName nvarchar(50), 
    PhoneNumber nvarchar(50)
)

具有这样的索引:

CREATE NONCLUSTERED INDEX IX_LastName ON TelephoneBook (
    LastName, 
    FirstName, 
    PhoneNumber
)

并想象该表有成千上万的行。

假设我要选择姓氏以B开头且名字为'John'的所有人。 我将编写以下查询:

SELECT 
    * 
FROM TelephoneBook 
WHERE LastName like 'B%' 
AND FirstName='John'

由于索引将所有以B开头的所有姓氏归为一组,因此可以帮助减少我们需要扫描的行数,所以它也可以对名字进行此操作吗? 还是数据库会扫描以B开头的每一行以查找名字为“ John”的行?

换句话说,第二,第三,第四,...列如何在索引中排序? 在这种情况下,它们也是按字母顺序排列的吗,所以找到Johanna很容易吗? 还是它们以某种随机或不同的顺序排列?

编辑:为什么我要问,是因为我刚刚读过上面的SELECT语句,索引将仅用于将搜索范围缩小到姓氏以B开头的记录,但是索引将不用于找到其中包含Johanna的所有行(并将诉诸于扫描所有“ B”行)。 我想知道为什么会这样吗? 我没有得到什么?

为了方便起见,索引的键用于where子句,直到第一个不等式。 like使用通配符被认为是一种不平等。

因此,索引将仅用于查找第一个值。 但是,可能会扫描条目以匹配名字,因此您仍然会使用索引。

当然,如果优化程序确定全表扫描更合适,则它可能根本决定不使用该索引。

在这种情况下,使用指定的查询,戈登的答案是正确的。 通常,您应该意识到,与其说是基于列的值,不如说是在“存储桶”中将记录分组在一起,而是根据索引的键列对它们进行排序。 换句话说,此索引中的记录将根据姓氏进行排序,对于共享相同姓氏值的记录,将按姓氏值然后按电话号码值进一步对其进行排序。 您没有为该索引上的列指定排序顺序,但是SQL Server将未指定的排序顺序默认为ASC(ending) ,因此这些列的确在索引中按词法排序。

在您的特定情况下,查询优化器已经决定查看第一列的索引,以确定要抓取的记录,正如戈登的答案所提到的那样,但是如果优化器认为更好,则SQL Server将对谓词进行重新排序,并且可能会使用更多索引的列或根本不包含列,具体取决于查询本身以及所查询记录的统计信息。

从逻辑上讲,索引是按键值按键顺序排序的。 因此,在这种情况下,姓氏(按文本排序),姓氏(按文本排序),然后是电话号码(按文本排序)...包含的所有列都不会排序。

在您的情况下,我们知道尾随的通配符仍然可以保存,因此我们希望看到一个索引试图从该数据池中将数据缩小到所有带有“ B”开头的姓氏(从“ B”开始)的数据,并将对其进行进一步过滤只包括那些具有FirstName ='John'的行。 您可以将其视为索引搜索,然后是范围搜索。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM