优化 NewOrg 表

您在使用现有层次结构数据填充表任务中创建的 NewOrd 表包含所有雇员的信息,该表使用 hierarchyid 数据类型表示层次结构。此任务添加了新的索引,以便支持对 hierarchyid 列的搜索。

聚集索引

hierarchyid 列 (OrgNode) 是 NewOrg 表的主键。此表创建时,其内包含了一个名为 PK_NewOrg_OrgNode 的聚集索引,用于强制实现 OrgNode 列的唯一性。此聚集索引还支持对表进行深度优先搜索。

非聚集索引

此步骤将创建两个非聚集索引,用于支持典型搜索。

为 NewOrg 表创建索引以提高搜索效率

  1. 若要改善在层次结构中同一级别的查询,可以使用 GetLevel 方法创建一个包含此层次结构中的此级别的计算列。然后,对此级别和 Hierarchyid 创建一个组合索引。运行下列代码以创建计算列和广度优先索引:

    ALTER TABLE NewOrg 
       ADD H_Level AS OrgNode.GetLevel() ;
    CREATE UNIQUE INDEX EmpBFInd 
       ON NewOrg(H_Level, OrgNode) ;
    GO
    
  2. EmployeeID 列创建一个唯一索引。即采用传统方式通过 EmployeeID 号单独查找一个雇员。运行下列代码以便对 EmployeeID 创建索引:

    CREATE UNIQUE INDEX EmpIDs_unq ON NewOrg(EmployeeID) ;
    GO
    
  3. 运行下列代码以分别按照三个索引的顺序从表中检索数据:

    SELECT OrgNode.ToString() AS LogicalNode,
    OrgNode, H_Level, EmployeeID, LoginID
    FROM NewOrg 
    ORDER BY OrgNode;
    
    SELECT OrgNode.ToString() AS LogicalNode,
    OrgNode, H_Level, EmployeeID, LoginID 
    FROM NewOrg 
    ORDER BY H_Level, OrgNode;
    
    SELECT OrgNode.ToString() AS LogicalNode,
    OrgNode, H_Level, EmployeeID, LoginID 
    FROM NewOrg 
    ORDER BY EmployeeID;
    GO
    
  4. 比较结果集以查看每类索引中的存储顺序。下面只显示了各输出的前四行。

    下面是结果集:

    深度优先索引:雇员记录存储在与相应经理的记录相邻的位置。

    LogicalNode OrgNode H_Level EmployeeID LoginID

    / 0x 0 1 zarifin

    /1/ 0x58 1 2 tplate

    /1/1/ 0x5AC0 2 4 schai

    /1/1/1/ 0x5AD6 3 9 jwang

    /1/1/2/ 0x5ADA 3 10 malexander

    /1/2/ 0x5B40 2 5 elang

    /1/3/ 0x5BC0 2 6 gsmits

    /2/ 0x68 1 3 hjensen

    /2/1/ 0x6AC0 2 7 sdavis

    /2/2/ 0x6B40 2 8 norint

    EmployeeID 优先索引:各行按照 EmployeeID 顺序存储。

    LogicalNode OrgNode H_Level EmployeeID LoginID

    / 0x 0 1 zarifin

    /1/ 0x58 1 2 tplate

    /2/ 0x68 1 3 hjensen

    /1/1/ 0x5AC0 2 4 schai

    /1/2/ 0x5B40 2 5 elang

    /1/3/ 0x5BC0 2 6 gsmits

    /2/1/ 0x6AC0 2 7 sdavis

    /2/2/ 0x6B40 2 8 norint

    /1/1/1/ 0x5AD6 3 9 jwang

    /1/1/2/ 0x5ADA 3 10 malexander

注意注意

有关显示深度优先索引和广度优先索引之间差异的关系图,请参阅使用 hierarchyid 数据类型(数据库引擎)

删除不需要的列

  1. ManagerID 列用于表示雇员/经理关系,现在由 OrgNode 列来表示。如果其他应用程序不需要 ManagerID 列,可以考虑使用下列语句删除该列:

    ALTER TABLE NewOrg DROP COLUMN ManagerID ;
    GO
    
  2. EmployeeID 列也是冗余列。OrgNode 列可以唯一标识每个雇员。如果其他应用程序不需要 EmployeeID 列,可以考虑使用下列代码先删除索引再删除该列:

    DROP INDEX EmpIDs_unq ON NewOrg ;
    ALTER TABLE NewOrg DROP COLUMN EmployeeID ;
    GO
    

使用新表替换原始表

  1. 如果您的原始表包含任何其他索引或约束,请将它们添加到 NewOrg 表中。

  2. 将旧的 EmployeeDemo 表替换为新表。运行下列代码以删除旧表,然后使用旧表的名称重新命名新表:

    DROP TABLE EmployeeDemo ;
    GO
    sp_rename 'NewOrg', EmployeeDemo ;
    GO
    
  3. 运行下列代码以检查最终表:

    SELECT * FROM EmployeeDemo ;
    

课程中的下一个任务

摘要:将表转换为层次结构