【问题标题】:SQL database experts: is this a bottleneck?SQL 数据库专家:这是瓶颈吗?
【发布时间】:2011-11-20 13:15:53
【问题描述】:

我说不,伙伴说是。我们都很固执。我们将进行测试,但我需要您提供一些弹药来支持我的案例,即以下伪代码不是那么大的瓶颈。我们正在做的是运行两个查询。第一个是针对一个大表(100k 记录),下面称为 BigTable。然后,我们获取我们找到的内容(通常是 30 条左右的记录)并针对一个小得多的表运行这些记录(在循环中,请参见下面的第二个“foreach”),称为 SmallTable,通常有大约 200 条记录。我的伙伴想要合并在 SmallTable 中找到的记录,以便它们出现在 BigTable 的记录中,但是如果这样做,您将失去灵活性并且数据库不再是正常形式。我的伙伴说他不关心正常形式,并声称下面是一个瓶颈。帮助我赢得这场战斗!当然,我的后备立场是“让我们测试一下看看”,但我现在可以使用一些火力。我们预计每秒 10 个请求之间(在这种情况下,瓶颈可能是微不足道的)或每秒最多 1500 个请求(这可能会在其他地方破坏我们的应用程序!哈哈。但我们是乐观主义者)。

平台:Microsoft SQL Server 2008,使用用 C# 和 Linq-to-Entities (EF) 编写的 Web 服务,在远程服务器上运行,该服务器不属于我们,但由 GoDaddy 等服务器公司拥有,位于“每次通话'/无状态基础。 SQL Server 中的所有内容都设置为默认值(例如,Max Pooling = 100、Load Balance Timeout = 0、Pooling = True)。我没有做任何缓存,因为我在某处读到缓存不适用于分布式数据库,我认为这家服务器公司使用。

我很感激。这是伪代码:

Public  string MyWebMethod()
{

List<Record> myrecords = new List<Records>();

try  //try block 1
{
using (AEntityFramework context = new AEntityFramework())
{
var RecordsReturned =   (from x in context.BigTable
                            //some conditions deleted
            select x);

//do some stuff with these records, typically 30 records returned from BigTable, which has 10000 to 100000 records total

foreach (Record r in RecordsReturned)
{  myrecords.Add(r);} //add these records to the List myrecords, to be used later.

}

}
catch (Exception)
{
Try block 1 exceptions here
}
//end of try block 1
//////////////////  now move to the next SQL query, which loops--is this a bottleneck?

foreach (Record R in myrecords)
{
try  //try block 2
{
using (AEntityFramework context = new EntityFramework())
{

    var SmallQuery = (from y in context.SmallTable
                      //some conditions deleted
         select y); 

//small table has 100 to 200 records, it is very small

//do a short operation with the Record R and anything collected by var SmallQuery, typically 2 to 3 entries.


}

}//end of try block 2

catch (Exception)
{
//try block 2 exceptions here
}

} //end of foreach

return “OK”;
}

[EDIT] 响应执行 JOIN 的答案。在这里没有答案,我将打开第二个线程。谢谢!请可怜新手。 好吧,我害怕这个。现在这个问题变了,也许我会打开一个新线程。

这是我的查询:

  • 表 ACustomers(包含客户 ID 和邮政编码)
  • Table CCategories(包含“食物”、“避难所”、“服装”等类别) (链接)表 A_C(因为表 A 和 C 是多对多链接的):包含“客户 ID”和类别,作为主键组合

我需要选择表 A 中满足条件的所有记录,然后根据链接表 A_C 中找到的参数列表过滤这些记录。但是我不知道参数列表的长度是多少,提前。它因方法调用而异。

举个具体的例子

表 A 有一个“客户 ID”和“邮政编码”列表。表 A_C 的主键包括“CustomerIDs”和“Categories”。表 C 有“类别”。我在表 A 中找到了居住在某个“邮政编码”中的客户。然后,从这个子集中,我需要找到这些客户中的哪些选择了某些产品,这些产品属于链接表表 A_C 中的某些类别:食品、服装等,但我的网络方法不提前知道这些类别是什么相反,它们是作为列表传递的:List myCategoryList(可以是 1 个类别或 100 个,因方法调用而异)。

如何使用 Linq-to-Entities 编写投影?

   List<string> CategoryList = new List<string>() { "Food", "Shelter", "Housing" }; // in one call to the web service method

   List<string> CategoryList = new List<string>() { "Food", "Clothing" }; //in a second call--varies and I don't know ahead of time which is which.

那么如何使用 Linq-to-Entities 进行投影?我将打开第二个线程。

【问题讨论】:

  • 为什么要在循环内运行 SmallQuery?那里有条件(选择)吗?如果是这样,您需要将其包含在“代码”中
  • 你的顽固伙伴还说你没有接受足够的答案。
  • @Erwin:这是向某人介绍相关常见问题解答的一种非常好的方式! :)

标签: sql sql-server-2008 profiling


【解决方案1】:

一般来说,您最好对正在处理的所有记录进行联接,并在代码中一次性处理它们。数据库服务器可能非常坚固,并且针对这样的组合进行了优化。这将比执行“伪连接”快得多,就像您在这里所做的那样(查询、循环另一个查询等)。

坚持(可能)第一范式。从长远来看,它会更好地为您服务。

【讨论】:

  • +1(假设我们对 SmallQuery 中发生的事情有所了解)
  • 我同意@ethrbunny,SQL 服务器将快速执行连接,因为它经过优化,它会比包括往返的 c# 代码更快......你没有提供任何信息根据您的数据/查询,但是(猜测)您应该考虑使用 EF 投影来创建组合结果集。
  • @ethrbunny--谢谢。我会考虑这一点,但问题是,我对 Linq-to-entities 的了解不够好,无法进行 Join,因为第二个查询涉及几个链接表。因此,鉴于我的无能,我猜你的回答认为我的合作伙伴是正确的,这是一个严重的瓶颈?
  • 我同意代码是一个潜在的瓶颈 - 但您的合作伙伴的解决方案并不理想。
  • @ethrbunny:你是说第三范式吗?
猜你喜欢
  • 2010-11-18
  • 1970-01-01
  • 1970-01-01
  • 2013-01-18
  • 2021-12-29
  • 2012-11-08
  • 2018-08-14
  • 1970-01-01
  • 2019-09-13
相关资源
最近更新 更多