TCM*_*TCM 6 sql sql-server-2005 sql-server-2008
我有一张自我加入的桌子.您可以将结构视为标准表来表示组织层次结构.如表: -
MemberId
MemberName
RelatedMemberId
Run Code Online (Sandbox Code Playgroud)
该表包含50000个样本记录.我写了CTE递归查询,它的工作非常好.然而,在我的机器上处理仅50000条记录所需的时间约为3分钟(4GB Ram,2.4 Ghz Core2Duo,7200 RPM HDD).
如何才能提高性能,因为50000不是那么庞大的数字.随着时间的推移,它将继续增加.这是我的存储过程中的查询.查询的目的是选择属于特定成员的所有成员.例如.在公司的所有者之下,每个人都来了.对于Manager,除了所有者返回所有记录.我希望你理解查询的目的.
设置ANSI_NULLS开启GO SET QUOTED_IDENTIFIER
Alter PROCEDURE spGetNonVirtualizedData
(
@MemberId int
)
AS
BEGIN
With MembersCTE As
(
Select parent.MemberId As MemberId, 0 as Level
From Members as parent Where IsNull(MemberId,0) = IsNull(@MemberId,0)
Union ALL
Select child.MemberId As MemberId , Level + 1 as Level
From Members as child
Inner Join MembersCTE on MembersCTE.MemberId = child.RelatedMemberId
)
Select Members.*
From MembersCTE
Inner Join Members On MembersCTE.MemberId = Members.MemberId
option(maxrecursion 0)
END
GO
Run Code Online (Sandbox Code Playgroud)
正如您所看到的那样,为了提高性能,我甚至在选择记录时最后一步创建了连接,以便不会将所有不必要的记录插入到临时表中.如果我在我的基本步骤和CTE的递归步骤(而不是在最后一步中选择)进行连接,则查询需要20分钟才能执行!
MemberId是表中的主键.
提前致谢 :)
在你的锚条件中你Where IsNull(MemberId,0) = IsNull(@MemberId,0)我假设这只是因为当你NULL作为参数传递时,=在返回IS NULL值方面不起作用.这将导致扫描而不是搜索.
WHERE MemberId = @MemberId OR (@MemberId IS NULL AND MemberId IS NULL)相反,使用哪个是 sargable.
另外我假设你不能有索引RelatedMemberId.如果没有,你应该添加一个
CREATE NONCLUSTERED INDEX ix_name ON Members(RelatedMemberId) INCLUDE (MemberId)
Run Code Online (Sandbox Code Playgroud)
(尽管您可以跳过包含的列位,如果MemberId是聚簇索引键,因为它将自动包含)
| 归档时间: |
|
| 查看次数: |
1535 次 |
| 最近记录: |