【问题标题】:optimizing a view for hierarchical data优化分层数据的视图
【发布时间】:2010-08-03 16:48:44
【问题描述】:

我目前有一个包含自联接的查询,用于从使用nested sets model 存储公司组织信息的表中查询员工的所有直接和间接经理。在此 SQL 表示法中,以冒号开头的数字(例如 :1)是变量:

select parent.empid, parent.depth from RelationshipMgr as node join
RelationshipMgr as parent on node.lft between parent.lft and parent.rgt
and node.empid = :1 order by parent.lft

通过将parent.depth = node.depth - :2 添加到联接条件或 where 子句中,我可以轻松地仅返回员工上方 n 级的经理的 ID(附带问题:哪个更快?)。

问题:我正在尝试将此查询转换为视图,但运气不佳。问题是我的大部分或所有变量都在我的查询的连接条件中。我目前最好的计划是将这些部分分成列,然后我可以在查询视图时使用 where 子句,例如:

select node.EmpID, parent.empid as MgrID, parent.depth as MgrDepth,
node.depth - parent.depth as MgrRelativeAltitude from RelationshipMgr as node
join RelationshipMgr as parent on node.lft between parent.lft and parent.rgt

您可以看到我必须发明MgrRelativeAltitude 列才能找到比员工高n 级的经理的 ID,但这并不是最大的问题。我担心这会产生严重的性能问题,因为 SQL Server 似乎是按照连接条件指定的方式进行完全连接,然后通过 where 子句对其进行过滤,而不是智能地使用 where 子句来限制连接。 有没有更好的方法来创建视图?我是否应该将其保留为查询并忘记制作视图?通过将其设为存储过程而不是视图,我会有所收获吗?

请不要说“过早的优化是邪恶的”......这并不为时过早。我要替换的实现使用了诸如混蛋邻接列表之类的东西,该列表具有将员工与其直接和间接经理中的任何一个相关联的记录……最坏的情况是 O(n^2) 记录,并且可以预见地遇到严重的性能问题时我们在层级中有超过 300,000 名员工。我的新嵌套集实现将缓解这些性能问题,除了这个查询...如果您在建议的视图上执行select *,结果将与我尝试替换的旧表几乎相同,并且这让我非常担心。

【问题讨论】:

  • 没有看到表格,我不确定数据的结构(不确定 LFT / Rgt 是什么。)如果您使用的是相对较新的 SQL Server;我会看看 CTE 来处理您的查询 - 您通常可以使复杂的东西更容易阅读。 MSSQL Tips 上的此页面使用了一个类似的示例,可能会有所帮助mssqltips.com/tip.asp?tip=1520
  • @u07ch 这是一个花园品种嵌套集模型......我的桌子结构真的没有什么特别之处。 “lft”和“rgt”是嵌套集技术的左右列(有时也分别称为向下和向上)。这些名称是相当标准的,因为“left”和“right”是 SQL 中的保留字。我在我的问题中提供了一个链接,但这是另一个(向下滚动到嵌套集部分):dev.mysql.com/tech-resources/articles/hierarchical-data.html

标签: sql sql-server query-optimization hierarchical-data nested-sets


【解决方案1】:

您正在尝试确定非相邻节点的层次关系。正如您所发现的,这是一个相对昂贵的运行时计算、视图或常规查询。相反,如果经常运行,我建议创建所谓的bridge table - 作为通过触发器更新的真实表或作为 SQL Server 2005+ 中的索引视图(尽管尚未尝试索引视图方法)。值得注意的是,与邻接表相比,嵌套集提供了更长的读取时间。

权衡是一个表的行数明显多于源表,因为它有效地表示了所有节点之间的关系,当添加、删除或父 ID 更改时它更新时,它会减慢写入速度。作为回报,您可以索引它并实现快速检索。如果更新网桥证明存在瓶颈,则优化是通过存储过程访问它,其中网桥用作频繁运行的输入组合的缓存,但在运行时计算不常见的情况。您需要评估底层节点表的读取与写入频率来做出决定。

An overview of options for representing hierarchical data in a RDBMS is available here.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-08
    • 1970-01-01
    • 1970-01-01
    • 2017-05-25
    • 2020-09-30
    • 2012-01-28
    • 1970-01-01
    相关资源
    最近更新 更多