簡體   English   中英

批量刪除行。 如何打開/重用 SQL Server 連接?

[英]Deleting rows by batches. How to open / reuse SQL Server connection?

如果我們要批量讀取要刪除的行,打開/使用 SQL Server 連接的最有效方法是什么?

foreach(IEnumerable<Log> logsPage in LogsPages)
{
    foreach(Log logEntry in logsPage)
    {
        // 1. get associated filenames
        // 2. delete row
        // 3. try delete each file
    }
}
  • 日志頁大小約為 5000 行
  • 與日志條目相關聯的文件大小可能不同。 我不認為它們比 500 Mb 大。
  • 我們使用 Dapper

我們應該讓 Dapper 在foreach循環的每一步打開連接嗎? 我想 SQL Server 連接池發生在這里?

或者我們應該每批打開一個顯式連接?

如果您在緊密循環中執行多個數據庫操作,通常最好在所有操作期間打開連接。 將連接返回到池在有爭議的系統中可能是有益的,在這種系統中,在下一次數據庫操作之前可能存在不確定的間隔,但如果您正在執行大量順序操作:不斷地從池中獲取和返回連接(並執行sp_reset_connection ,它發生在幕后)無緣無故地增加開銷。

因此,明確地說,我將Open[Async]()放在第一個foreach之上。

注意:對於批處理,您可能會發現有一些方法可以減少往返次數,特別是利用基於 id 的 Dapper 中的IN重寫。 既然你提到了 SQL-Server,這可以與將SqlMapper.Settings.InListStringSplitCount設置為正數相結合(5、10 等是合理的選擇;注意這是一個全局設置); 例如,對於一個簡單的場景:

connection.Execute("delete from Foo where Id in @ids",
    new { ids = rows.Select(x => x.Id) });

有效:

foreach (var row in rows)
{
    connection.Execute("delete from Foo where Id = @id",
        new { id = row.Id });
}

如果沒有InListStringSplitCount ,第一個版本將被重寫為:

delete from Foo where Id in (@ids0, @ids1, @ids2, ..., @idsN)

使用InListStringSplitCount ,第一個版本將被重寫為:

delete from Foo where Id in (select cast([value] as int) from string_split(@ids,','))

這允許多次使用完全相同的查詢,這有利於查詢計划的重用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM