【问题标题】:Is it worth doing parallel reading from different tables in the same database是否值得从同一个数据库中的不同表进行并行读取
【发布时间】:2014-06-14 20:53:32
【问题描述】:

在我正在开发的一个应用程序中,它需要从同一个 SQL Server 数据库中的大约 5 到 10 个表中读取数据,将它们加载到多个 List 中,然后处理数据。从每个表返回的行数各不相同,有些是 1 行,有些是大约 1,000 行。

该应用程序是用 C# 4.0 编写的,因此我正在考虑使用任务并行库并启动多个任务以同时从这些表中检索数据。我认为这比调用按顺序从这些表中返回数据的单个查询要快,但不确定。所以我的问题是:

  1. 考虑到打开多个数据库连接等开销,使用多个任务检索数据真的会更快吗?
  2. 如果在某些情况下答案是肯定的,那么在哪些情况下答案是否定的?
  3. 如果答案是否定的,是否有任何替代方法?
  4. 在使用多个任务检索数据时还需要考虑其他事项吗?

为了缩小范围,您可以做出以下假设:

  • 数据处理不是问题的一部分。仅数据检索。
  • 其中一些表与 FK 相关。像父母
  • 这些表仅包含 varchar 和 numeric 列,并且行大小小于 400 字节。
  • 普通 ADO.NET(例如 SqlConnection/SqlCommand/SqlDataReader)用于从每个表中检索数据
  • 每个任务都会调用一个自包含的方法,该方法从 SqlDataReader 读取数据并返回一个对象列表。
  • 数据库服务器功能强大,足以处理所有并发连接和查询。
  • 如果使用单个查询来检索序列中的所有数据,客户端计算机的功能足以处理数据操作。它能够进行多线程处理。
  • 如果使用单个查询,网络传输数据的速度足够快

提前感谢您的宝贵时间和意见!

【问题讨论】:

  • 如果您对如此 微小 的数据量有疑问,您应该查看映射代码,即如何将结果转换为对象列表、查询和您的数据访问代码。 代码在哪里
  • 对于您的问题,我们目前在加载数据方面没有问题。我只是在想使用并行会使其更快。如果它没有伤害任何东西,我们为什么不这样做呢。
  • 确实伤害 - 多个连接会导致数据库负载更大和并发问题,多次往返会增加延迟和延迟,代码变得更加复杂。除非你说的是几十万行,否则并行加载是没有意义的。

标签: c# sql-server task-parallel-library


【解决方案1】:

首先要说我不认为这是您在这种情况下需要关注的内容。数据量在这里似乎不是问题,所以我会专注于其他地方。

回答您的一些问题。是的,并行加载可以提高性能,但通常在数据(行数)大得多的情况下。不过,您确实需要注意内存占用量,因为您不想杀死所有数据都在内存中的服务器。

如果您多次且非常频繁地运行此操作,我会说您需要专注于此。

与往常一样,在成为问题之前不要进行优化。

编写可理解和可维护的代码更为重要。几个月后,当您需要修改此代码时,您将感谢您的明星。

还有,你试过什么?

您是否进行过任何基准测试?编写一个小应用程序并将这两种情况循环几次(数百甚至数千次)并测量它所花费的时间。 使用Stopwatch 看看时差是多少。

【讨论】:

  • 感谢您的快速回复。我想设计应用程序,以便它能够更好地适应更大的数据量。我担心并行是否会在指定的情况下产生负面影响,或者是否值得这样做。我认为从其他人那里获得一些意见会很好。对于您的问题,我之前在几个 Web 应用程序中进行了并行加载,它大大缩短了加载时间,但我没有进行任何基准测试。
  • 您的数据量很少。如果您有问题,则问题出在您的代码中,而不是数据库中。如果您使用返回多个结果的单个 SQL 批处理,您可能会发现它比并行加载更更快,因为往返和解析更少
  • 感谢您的意见@Panagiotis Kanavos。我们目前在加载数据时没有问题,最初的计划是使用单个存储过程返回多个结果。但是,由于未来数据量可能会增长,我们希望积极主动,以便更好地扩展。我得到的是,它现在有点过头了,也许我们应该只在它成为问题时才考虑它?
  • 我会将此标记为答案,因为我认为 asstander 提出了一个很好的观点,如果它不会引起问题,请不要优化它。它可以节省时间,让事情变得更容易。
【解决方案2】:

最多 1000 行的 10 个表听起来像是少量数据。与其打开多个连接并执行并行处理,我宁愿只有一个存储过程返回所有不同的表并使用 dataReader.NextResult() 一个一个地读取它。

查看以下 StackOverflow 问题的已接受答案 Multiples Table in DataReader

【讨论】:

  • 感谢您的意见@Romeo。我的一部分也是这么想的,但我也觉得启动多个任务并不太复杂。所以,如果这样做有好处,我们为什么不呢?
【解决方案3】:

我会说“这取决于”场景。让我解释一下,如果一个任务不依赖于另一个并行任务的查询或处理结果,那么产生几个并行检索任务和后续处理将“更快”。如果您走这条路线,请查看稍微过时但仍然相关的"Concurrency & Coordination With Futures in C#"C# async, await feature

我的某些部分认为您引入了可以在需要时探索/调查的复杂性,并且只设计现在需要的东西。

在走并行路线之前,请探索使用 jQuery/ajax 对“网页”(我假设是一个网络应用程序)的不同部分进行延迟加载的可能性,以提高网页的感知响应能力。

无论您选择哪种方法,都应该使用 YSlow 或类似工具来分析网页。

对不起!

【讨论】:

  • async,await 是异步工作,不是并行
  • 感谢@Param Pavar。这些任务的结果是相关的,但我认为它们在数据检索过程中并不依赖。结果将被处理而不是显示在网页中,所以我个人认为在这种情况下延迟加载不会“加快速度”。我不知何故觉得在数据检索中使用并行不会增加太多复杂性,但在数据处理中使用 is 会。所以我想在这一点上专注于数据检索。
猜你喜欢
  • 2022-06-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-27
  • 1970-01-01
相关资源
最近更新 更多