我正在为我的客户设计一个金字塔方案,他将把这个结构应用到系统中。这是一个推荐计划,如果介绍有人加入该网站,所有上层都将享受到referal费用。
这是我的表结构,因此根据列的引用,我可以找回特定用户的所有上行或下行。
然而,当我使用此语句循环时,(抱歉无法提供完整的代码,因为它很大,但可以通过以下代码轻松理解)
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秒获得所有数据都出来了。因此,存储过程不是一个选择,因为它在执行时仍然会变慢
我是否知道如何在10秒内通过此金字塔方案获取所有数据?我不介意索引,但是我通过结果对引用的索引仍然很慢
答案 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
备注:
资源
答案 1 :(得分:-1)
您可以很好地使用Indexing。对于您的情况,您可以使用主索引或群集索引。 为此,您首先需要确定经常使用的列和查询。为此你需要一次又一次地修改你的ER模型。我希望性能得到改善
通过查看你的SQL表,我假设你可能没有正确地完成ER模型。在你的表中有这么多的空列是一个糟糕的方法。 所以,从根开始然后自动你会看到差异。
您的参考:Indexing