从多个运行缓慢的数据库中获取数据的方法

时间:2015-06-16 15:56:19

标签: c# sql algorithm linq linq-to-sql

我有一些方法需要从多个数据库中获取统计数据。关键的想法是每个表都包含一个DBName,并从中向下钻取到客户端主数据库,调用具有所需数据库名称的存储过程。最后,我再次向下钻取来从客户的项目数据库中获取数据。

总结一下:

  1. 我获取了所有云用户的列表。

  2. 对于每个用户,我通过在他的主DB上使用存储过程来获取他的客户端 - >标记为userClients。

  3. 对于每个客户,我使用Clients Project DB上的存储过程来获取他的统计信息。

  4. 执行非常少的数据需要大约5-6秒。

    public List<CloudAnalysisDTO> GetCloudAnalysisForPeriod(DateTime FromDate, DateTime ToDate)
        {
            var users = FindAll();
            List<CloudAnalysisDTO> resultsList = new List<CloudAnalysisDTO>();
            HashSet<string> userclients = new HashSet<string>();
    
            using (var db = new ProjSQLDataContext(conn))
            {
                foreach (var user in users)
                {
                    if (user.ID == 0)
                        continue;
    
                    var ids = string.Join(",", db.UserClients.Where(uc => uc.UserId == user.ID).Select(uc => uc.ClientId.ToString()).ToArray());
                    var mainDB = user.MainDB;
    
                    if (mainDB.Length == 0 || ids.Length == 0)
                        continue;
    
                    List<CloudAnalysisDTO> userClients =
                            db.ExecuteQuery<CloudAnalysisDTO>(@"EXEC CloudUsersAnalysis {0},{1}", mainDB, ids).ToList<CloudAnalysisDTO>();
    
                    List<CloudAnalysisDTO> needRemove = new List<CloudAnalysisDTO>();
    
                    foreach (var client in userClients)
                    {
                        if (!userclients.Contains(user.MainDB + client.ClientID.ToString()))
                            userclients.Add(user.MainDB + client.ClientID.ToString());
                        else
                        {
                            needRemove.Add(client);
                            continue;
                        }
    
                        ClientAnalysisDTO clientAnalysisDTO =
                        db.ExecuteQuery<ClientAnalysisDTO>(@"EXEC CloudClientAnalysis {0},{1},{2}", client.ProjectDB, FromDate, ToDate).SingleOrDefault<ClientAnalysisDTO>();
    
                        if (clientAnalysisDTO != null)
                        {
                            client.ClientAnalysisDTO = clientAnalysisDTO;
                        }
    
                        client.UserID = user.ID;
                        client.MainDB = user.MainDB;
                    }
    
                    foreach (var removeDTO in needRemove)
                    {
                        userClients.Remove(removeDTO);
                    }
    
                    if (userClients != null && userClients.Count > 0)
                        resultsList.AddRange(userClients);
                }
    
    
    
            }
            return resultsList;
        }
    

    我可以采取哪些措施来提高绩效?

2 个答案:

答案 0 :(得分:0)

我要做的第一件事是启用.NET跟踪,并在每次调用之前和之后在tracelog中写一行。

https://msdn.microsoft.com/en-us/library/zs6s4h68(v=vs.110).aspx

这句话让我怀疑你可能会偷偷地在&#34;&#34;其中一个查询中的子句,可能不是高效的:

 var ids = string.Join(",", db.UserClients.Where(uc => uc.UserId == user.ID).Select(uc => uc.ClientId.ToString()).ToArray());

下一步一旦找到弱表现者(上面一行只是我猜),你应该启用数据库分析,以确定需要新索引或数据库维护的位置。

答案 1 :(得分:0)

我自己使用纯sql存储过程来获取数据。你可以找到我的解决方案here