C# 在不使数据库过载的情况下运行大量简单查询的最有效方法是什么?

C# 在不使数据库过载的情况下运行大量简单查询的最有效方法是什么?,c#,.net,sql-server,asynchronous,async-await,C#,.net,Sql Server,Asynchronous,Async Await,假设我有一个方法 public async Task SaveItemToDb(ItemEntity item) { ... } 它将单个项目保存到数据库中,假设我需要使用500000个项目运行它,并且出于业务原因,我无法执行批量操作(例如,我无法创建SaveItemsToDb(IEnumerable items)) 我想知道这样做的最好方法是什么,这样我就不会因为同时运行的查询而使数据库过载,而每个查询都可以被认为是相互独立的。任务就是这种情况。当所有(…)时?您可以确保最多运行numta

假设我有一个方法

public async Task SaveItemToDb(ItemEntity item) { ... } 
它将单个项目保存到数据库中,假设我需要使用500000个项目运行它,并且出于业务原因,我无法执行批量操作(例如,我无法创建
SaveItemsToDb(IEnumerable items)


我想知道这样做的最好方法是什么,这样我就不会因为同时运行的查询而使数据库过载,而每个查询都可以被认为是相互独立的。
任务就是这种情况。当所有(…)
时?

您可以确保最多运行
numtask
。最后的技巧是确保你等到所有任务完成。不幸的是,它没有异步版本,所以会阻塞,但这可能不是什么大问题

下面的代码无法正确处理任何任务中的错误。你可能想改进它

async Task ProcessTasks(IEnumerable<Task> tasks, int numTasks){
    var count = new CountDownEvent(0);
    SemaphoreSlim semaphore = new SemaphoreSlim(numTasks);
    foreach(var task in tasks){
        await semaphore.WaitAsync();
        task.ContinueWith(_=>{
            semaphore.Release();
            count.Signal();
            }
        );
    }
    count.Wait(); // Wait till the count reaches zero
}
异步任务处理任务(IEnumerable任务、int numtask){
变量计数=新的倒计时事件(0);
SemaphoreSlim semaphore=新的SemaphoreSlim(numTasks);
foreach(任务中的var任务){
wait semaphore.WaitAsync();
task.ContinueWith(=>{
semaphore.Release();
count.Signal();
}
);
}
count.Wait();//等待计数为零
}

帮助数据库的一种方法是将所有查询编译成一个块并执行它。@ShemeerBK你能详细说明一下吗?嗨,我不确定我是否正确理解你的方案,在我以前的项目中,我遇到了这样的问题,因为我必须为每个创建的对象运行insert语句。问题是,在数据层,每次打开连接时,都会执行查询,然后关闭连接。将插入操作拖了一段时间。简单的解决方法是在一个类中收集所有这些插入查询,并使用计时器以100个块的形式执行。也许这有助于你的案例。重新审视业务原因。您已经知道了正确的解决方案——运行更少但更复杂的查询,这样数据库就可以在更多的工作中分摊其交易成本。任何与效率相关的问题都会导致投机争论,如果不进行衡量,就无法解决。插入50万行是一个批量操作,也就是说,不管您是否喜欢执行批量操作。如果您担心数据库过载,那么您需要在您的环境中进行负载测试。没有测量的猜测不是前进的方向。