金字塔循环的性能调整

时间:2017-12-26 04:25:21

标签: c# sql

我正在为我的客户设计一个金字塔方案,他将把这个结构应用到系统中。这是一个推荐计划,如果介绍有人加入该网站,所有上层都将享受到referal费用。

enter image description here

这是我的表结构,因此根据列的引用,我可以找回特定用户的所有上行或下行。

然而,当我使用此语句循环时,(抱歉无法提供完整的代码,因为它很大,但可以通过以下代码轻松理解)

for (int a = 0; a < lowerLine.Count; a++)
{
    var query3 = from data in db.users_table where data.referral_by == referralUser && data.is_activated == true select new{ data.user_id,data.introducer};
    var lowerLine2 = query3.ToList();
    lowerLineCount2 += lowerLine2.Count;
    totalCount += lowerLine2.Count;
}

这是一个linq语句,它会一直循环到金字塔的末尾以获得全部推荐。但是,如果执行此操作,如果他有500个referal,获取所有数据将变得非常慢。

在这种情况下,我认为通过存储过程获取所有数据的解决方案,但是当我尝试执行该语句500次时,性能仍然是26秒仍然非常慢,我的要求是最多10秒获得所有数据都出来了。因此,存储过程不是一个选择,因为它在执行时仍然会变慢 enter image description here

我是否知道如何在10秒内通过此金字塔方案获取所有数据?我不介意索引,但是我通过结果对引用的索引仍然很慢

2 个答案:

答案 0 :(得分:0)

首先,使用char(n)是一个坏习惯,很容易导致问题,我总是使用NVARCHAR(n)来输入用户数据。

其次,您可能希望查看存储过程中的Recursive Common Table Expression (CTE)。根据表格大小和其他因素,它可能会比通过EF查询提供更好的性能。但是,标准的T-SQL循环也值得测试,请参阅下面的更多资源。

最后,我不确定这是一个EF代码优先方法,而你的referral_by是一个导航属性,虽然id确保它以任意方式被正确索引< / p>

...

以下代码只是尝试列出@SomeUser的引用树列表(即根据原始问题新添加的成员)。我不完全确定你要用最低线的东西做什么

<强> CTE

With UserCte as
(
  //Anchor Query
  Select user_id, first_name, last_name, referral_by from users Where user_id=@SomeUser
  Union all
  //Recursive Query
  Select U.user_id, U.first_name, U.last_name, U.referral_by from users U
  Inner Join UserCte M //Joining with anchor member
  On U.user_id = M.user_id
)

//Returning all user of user_id @SomeUser
Select * from UserCte 

备注

  • 这只是一个例子,尚未经过测试,但它应该指向更好的方向
  • 没有严格的规则和性能,对某人有利的事情可能对你不利,最好在你自己的系统上用这些类型的东西做你自己的基准测试

资源

Using Common Table Expressions

Optimize Recursive CTE Query

答案 1 :(得分:-1)

您可以很好地使用Indexing。对于您的情况,您可以使用主索引或群集索引。 为此,您首先需要确定经常使用的列和查询。为此你需要一次又一次地修改你的ER模型。我希望性能得到改善

通过查看你的SQL表,我假设你可能没有正确地完成ER模型。在你的表中有这么多的空列是一个糟糕的方法。 所以,从根开始然后自动你会看到差异。

您的参考:Indexing