使用多线程来执行SQL语句

时间:2014-05-19 13:22:34

标签: c# sql .net multithreading oracle

我有执行数据检索的代码 - 基本上执行3到12个SQL(oracle)读取语句以检索有关对象的数据。

不幸的是它的运行缓慢(特别是没有SQL语句,它只是我有这么多的事实 - 它们每个语句花费大约0.2秒,这意味着代码完成时间超过2秒)。

我正在研究改善性能的方法。一种方法是将一些表合并为单个查询(可以将组合结果减少0.5秒)。然而合并其余部分没有意义,因为在某些情况下只有数据存在,并且试图确定何时有数据可能会变得棘手。

我正在考虑在我的程序中引入线程,所以在初始查询之后,我会为每个其他查询生成一个线程,因此它们会同时执行。但是,我从未使用过线程,并且对引入死锁或其他陷阱感到担心。

目前,其他查询将结果封送到SAME对象的不同部分。这会导致任何问题(即,因为我们通过对象内的不同部分/字段访问/更新不同线程中的相同对象吗?)。在所有线程完成后,将结果和编组返回到对象中会更好吗?

我知道这些类型的问题很难回答,因为它有更一般的建议,但如果有人认为这是一个好主意,或者有其他建议,我会很感激吗?

2 个答案:

答案 0 :(得分:0)

如果您只是在阅读(从中选择) - 请不要担心死锁。 Oracle读数不可阻止(大多数情况下)。线程查询到oracle的最大问题是如何处理连接。要创建连接,请运行查询并关闭连接 - 非常非常糟糕。连接很昂贵。它们也是有限的,因此您不想创建一百万个连接来执行您的逻辑。

因此,您将使用某种连接池并将查询放入队列中。

另外,我希望您使用绑定变量而不是字符串连接来将查询传递给oracle。

通常,我会收集所有数据(在一个查询中更好),然后才更新对象。你也可以考虑将你的物体制成它们。

答案 1 :(得分:0)

线程工作完美。 2年前,我做了一个项目,使用多个多线程/多线程的方法将数据推送到oracle数据库(并从中提取一些数据以进行更新)。

我基本上使用了一个分阶段的方法(一个请求将经历多个阶段,在那里消耗,新数据被pusehd用于下一个阶段)并且每个阶段都使用一个可配置的线程池,它将接收消息,处理它并发布新消息。

我们认为当时接近200个线程每分钟处理大约一百万条SQL语句(点击Oracle Exadata实际上已经完成了一些工作)。

所以,多线程"只是工作" - 显然,如果你知道如何做到这一点,你必须让你的架构和sql语句很好,不阻塞。一般而言,数据库完全可以处理多个线程。

现在,详情请参阅。

示例:

  

目前,其他查询将结果编组为不同的   SAME对象的各个部分。这会导致任何问题(即从那以后)   我们正在访问/更新不同线程中的相同对象   对象中的不同部分/字段?)

只要:

,绝对没问题
  • 在将对象移至下一阶段和
  • 之前,您已完成所有更新
  • 更新不重叠或具有基数(1必须完成2才能获得所需数据)。

这些是实现细节,很难为那些(完全不可能)做出通用答案。特别是因为这是多线程101 - 并且与任何数据库访问无关。

通常 - 您还必须调整线程数。 .NET本身无法做到这一点 - 因为它会看到CPU不忙并产生更多线程,即使数据库服务器是瓶颈。这就是为什么我们采用多个阶段 - 所以我们可以根据他们的工作调整线程数量(最后阶段使用批量插入将聚合数据插入到具有少量线程的临时登台表中,移动大量数据在每个声明中 - 这将需要一些调整可能性,以避免数据库端完全过载。)