1

一个观点我现在有一个包含自联接查询一个员工的所有直接和间接的管理人员从存储使用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要么连接条件返回一个管理器的雇员Ñ水平高于只ID或者where子句(侧面问题:哪个更快?)。

问题:我想把这个查询变成一个视图,我没有太多的运气。问题是我的大部分或全部变量都处于查询的连接条件中。我目前最好的计划是打破那些部分到列,我可以再使用,当我查询视图的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)记录,并且可预见地遇到了严重的性能问题我们在层次结构中拥有超过30万名员工。我的新嵌套集实现将缓解这些性能问题,除了这一个查询...如果您在建议视图上执行select *,结果将与我试图替换的旧表几乎相同,我非常。

+2

没有看到我不知道数据是如何构成的表(不知道什么LFT/RGT是。)如果你是一个相对较新的SQL Server上;我会看看CTE处理你的查询 - 你经常可以使复杂的东西更容易阅读。MSSQL Tips上的这个页面使用了一个类似的例子,它可能对你有帮助 http://www.mssqltips.com/tip.asp?tip=1520 – u07ch 2010-08-04 09:06:32

+0

@ u07ch它是一个花园类的嵌套集模型...真的没有对我的桌子结构没什么特别的。 “lft”和“rgt”分别是嵌套技术的左列和右列(有时也分别称为向下和向上)。这些名称相当标准,因为“左”和“右”是SQL中的保留字。我在我的问题中提供了一个链接,但这里是另一个(向下滚动到嵌套集的部分):http://dev.mysql.com/tech-resources/articles/hierarchical-data.html – rmeador 2010-08-04 14:03:47

回答

0

您正试图确定非相邻节点的层次关系。如你所见,这是一个相对昂贵的运行时间计算,查看或定期查询。相反,如果经常运行,我会建议创建所谓的bridge table--要么是通过触发器更新的实际表格,要么是SQL Server 2005+中的索引视图(尽管还没有尝试索引视图方法)。值得注意的是,与邻接列表相比,嵌套集提供了优越的读取时间。

,这种交易是比源显著多行的表,因为它有效地代表减慢写,因为它更新节点的增加,删除或父IDS随时改变所有节点之间的关系。作为回报,您可以对其进行索引并实现快速检索时间。一个优化,如果更新桥证明是一个瓶颈,通过一个存储过程来访问这个桥,这个桥可以作为缓存来用于频繁运行的输入组合,但是可以在运行时计算不常见的情况。您需要评估底层节点表的读取频率和写入频率以作出决定。

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