优化 NewOrg 表
您在使用现有层次结构数据填充表任务中创建的 NewOrd 表包含所有雇员的信息,该表使用 hierarchyid 数据类型表示层次结构。此任务添加了新的索引,以便支持对 hierarchyid 列的搜索。
聚集索引
hierarchyid 列 (OrgNode) 是 NewOrg 表的主键。此表创建时,其内包含了一个名为 PK_NewOrg_OrgNode 的聚集索引,用于强制实现 OrgNode 列的唯一性。此聚集索引还支持对表进行深度优先搜索。
非聚集索引
此步骤将创建两个非聚集索引,用于支持典型搜索。
为 NewOrg 表创建索引以提高搜索效率
若要改善在层次结构中同一级别的查询,可以使用 GetLevel 方法创建一个包含此层次结构中的此级别的计算列。然后,对此级别和 Hierarchyid 创建一个组合索引。运行下列代码以创建计算列和广度优先索引:
ALTER TABLE NewOrg ADD H_Level AS OrgNode.GetLevel() ; CREATE UNIQUE INDEX EmpBFInd ON NewOrg(H_Level, OrgNode) ; GO
对 EmployeeID 列创建一个唯一索引。即采用传统方式通过 EmployeeID 号单独查找一个雇员。运行下列代码以便对 EmployeeID 创建索引:
CREATE UNIQUE INDEX EmpIDs_unq ON NewOrg(EmployeeID) ; GO
运行下列代码以分别按照三个索引的顺序从表中检索数据:
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
比较结果集以查看每类索引中的存储顺序。下面只显示了各输出的前四行。
下面是结果集:
深度优先索引:雇员记录存储在与相应经理的记录相邻的位置。
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 数据类型(数据库引擎)。 |
删除不需要的列
ManagerID 列用于表示雇员/经理关系,现在由 OrgNode 列来表示。如果其他应用程序不需要 ManagerID 列,可以考虑使用下列语句删除该列:
ALTER TABLE NewOrg DROP COLUMN ManagerID ; GO
EmployeeID 列也是冗余列。OrgNode 列可以唯一标识每个雇员。如果其他应用程序不需要 EmployeeID 列,可以考虑使用下列代码先删除索引再删除该列:
DROP INDEX EmpIDs_unq ON NewOrg ; ALTER TABLE NewOrg DROP COLUMN EmployeeID ; GO
使用新表替换原始表
如果您的原始表包含任何其他索引或约束,请将它们添加到 NewOrg 表中。
将旧的 EmployeeDemo 表替换为新表。运行下列代码以删除旧表,然后使用旧表的名称重新命名新表:
DROP TABLE EmployeeDemo ; GO sp_rename 'NewOrg', EmployeeDemo ; GO
运行下列代码以检查最终表:
SELECT * FROM EmployeeDemo ;