gpt4 book ai didi

c# - 多线程 SQL 选择语句

转载 作者:太空宇宙 更新时间:2023-11-03 21:00:12 25 4
gpt4 key购买 nike

本人是多线程新手,也是SQL新手,菜鸟犯错请见谅。

我正在尝试异步执行许多 SQL 查询。查询都是来自同一数据库中同一表的所有选择语句。我可以同步运行它们并且一切正常,但是测试一小部分让我相信同步运行所有查询大约需要 150 小时,这太长了。因此,我试图弄清楚如何并行运行它们。

我尝试在 run a method multiple times simultaneously in c# 的答案之后对代码建模,但我的代码没有正确执行(这是错误的,虽然我不知 Prop 体是如何发生的。代码只是说发生了错误)。

这是我所拥有的(我实际正在做的事情的一个更小更简单的版本):

class Program
{
static void Main(string[] args)
{
List<string> EmployeeIDs = File.ReadAllLines(/* Filepath */);
List<Tuple<string, string>> NamesByID = new List<Tuple<string, string>>();

//What I do not want to do (because it takes too long) ...
using (SqlConnection conn = new SqlConnection(/* connection string */))
{
foreach (string id in EmployeeIDs)
{
using (SqlCommand cmd = new SqlCommand("SELECT FirstName FROM Employees WITH (NOLOCK) WHERE EmployeeID = " + id, conn))
{
try
{
conn.Open();
NamesByID.Add(new Tuple<string, string> (id, cmd.ExecuteScalar().ToString()));
}
finally
{
conn.Close();
}
}
}
}


//What I do want to do (but it errors) ...
var tasks = EmployeeIDs.Select(id => Task<Tuple<string, string>>.Factory.StartNew(() => RunQuery(id))).ToArray();
Task.WaitAll(tasks);
NamesByID = tasks.Select(task => task.Result).ToList();
}

private static Tuple<string, string> RunQuery(string id)
{
using (SqlConnection conn = new SqlConnection(/* connection string */))
{
using (SqlCommand cmd = new SqlCommand("SELECT FirstName FROM Employees WITH (NOLOCK) WHERE EmployeeID = " + id, conn))
{
try
{
conn.Open();
return new Tuple<string, string> (id, cmd.ExecuteScalar().ToString());
}
finally
{
conn.Close();
}
}
}
}
}

注意:我不关心这是如何实现多线程的(任务、parallel.foreach、backgroundworker 等)。这将用于运行 ~30,000 个选择查询恰好 1 次,所以我只需要它快速运行一次(我希望 ~8 小时 = 一个工作日,但我会尽我所能)一次.它不一定非常漂亮。

提前致谢!

最佳答案

这完全是错误的。您应该构建一个查询来选择您需要的所有 FirstNames。如果你需要向服务器传递一堆 id,那没问题,只需使用 table valued parameter (又名 TVP),逗号分隔的值列表确实不能很好地扩展。如果查询被正确编写并且表被索引,那应该是相当快的。 100k 行表是一个小表。

查询可能看起来像这样

SELECT DollarAmount, comp.CompanyID
FROM Transactions
JOIN (SELECT MIN(TransactionID) as minTransactionID, CompanyID
FROM CompanyTransactions
GROUP BY CompanyID
) AS comp
ON Transactions.TransactionID = comp.minTransactionID
JOIN @IDList ON id = comp.CompanyID

如果 TVP 中的 ID 不唯一,您可以使用 IN 而不是 JOIN

顺便说一句。你知道NOLOCK是什么意思吗?如果您是数据库的唯一用户并且单线程使用它或不修改任何数据,那么您是安全的。除此之外,这意味着您还可以:

  • 结果中可能缺少一些记录
  • 结果中有重复记录
  • 结果中有一些行从未被提交,也从未被接受为有效数据
  • 如果您使用 varchar(max),您可能会得到从未存储过的文本

关于c# - 多线程 SQL 选择语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46208535/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com