【问题标题】:How NonClustered Index works in SQL Server非聚集索引在 SQL Server 中的工作原理
【发布时间】:2015-02-07 20:33:03
【问题描述】:

我有一个问题,与 DB 理论有关:

假设我们有一个包含 3 列的表:[PersonID], [PersonName], [PersonAge]

我们知道,当我们有一个按一列的非聚集索引时,SQL Server 会按照指定的列对表数据进行排序,并从中构建 B+ 树。当我们需要使用这样的索引查找行时,SQL Server 通过比较一个原子数据对象(例如intstring)来扫描 B++ 树。很清楚,当我们按一列构建非聚集索引时(假设[PersonName]),非聚集索引是如何工作和查找数据的,但是如果我们按两列创建非聚集索引:[PersonName][PersonAge] 会怎样?

我知道,在排序过程中,最重要的标准将是[PersonName],如果有几条记录相同,那么它们将按[PersonAge] 排序。但是,SQL Server 将如何根据该索引物理处理 B++ 树?

当它应该执行查询时如何使用这样的树

SELECT * 
FROM dbo.Person 
WHERE [PersonName] = 'Bob' AND [PersonAge] = 45

感谢您的解释。

【问题讨论】:

    标签: sql sql-server indexing b-tree non-clustered-index


    【解决方案1】:

    非聚集索引与只有一列的索引几乎相同 - 但 B++ 导航树中的每个索引条目将有 两个 列值(PersonName, PersonAge)

    由于两列具有可比性,因此将应用明确定义的排序 - 首先是 PersonName,然后是 PersonAge - 所以您的导航树项目看起来像这样(如果作为平面列表查看):

    Alice,42
    Alice,57
    Andrew,31
    Anthony,23
    ...
    ...
    Bertrand,48
    Bob,34
    Bob,39
    Bob,44 
    Bob,45
    Bob,58
    ......
    Zachary,19
    

    当您运行查询时

    SELECT * 
    FROM dbo.Person 
    WHERE [PersonName] = 'Bob' AND [PersonAge] = 45
    

    然后 SQL Server 将导航 B++ 导航树 - 首先查看 PersonName,直到找到所有出现的 Bob,然后它扫描所有 Bob 以找到您正在寻找的那个(或者也许它没找到)。

    【讨论】:

    • 谢谢您的提前。所以,如果我理解正确,SQL Server 会找到 [PersonName] 为“Bob”(搜索操作)的所有记录,然后它会扫描每个记录并与 45(年龄值)进行比较?如果是这样,通过 [PersonAge] 参数排序有什么意义?它给我们带来了哪些利润?
    • @Alex44:如果您没有索引中有PersonAge - 那么SQL Server如何找到正确 Bob?它不能 - 它必须获取它找到的 all Bobs,转到实际数据页面(在聚集索引叶级别中)并检查那里的 PersonAge 属性。这将导致几个非常昂贵的 Key Lookup 操作,因此会严重影响性能
    猜你喜欢
    • 2011-05-13
    • 2012-10-01
    • 2018-05-08
    • 1970-01-01
    • 2021-04-10
    • 2011-05-21
    • 1970-01-01
    • 2011-11-30
    相关资源
    最近更新 更多