gpt4 book ai didi

sql-server - 为什么每次插入临时表一个 I/O?数据库服务器

转载 作者:行者123 更新时间:2023-12-03 11:19:35 25 4
gpt4 key购买 nike

在一个简单的测试程序中,我启动一个事务,创建一个#temp 表和两个索引,向表中插入一堆行,然后提交。

查看 Sql Server 的任务管理器 I/O 写入,我看到每个表插入有 1 个磁盘写入。这让我感到惊讶,因为#temp 表是不可恢复的,所以除非有内存压力,否则不需要写入或记录,即使需要记录,我希望日志写入操作的数量最少,而不是每次插入 1 次.相反,通过 20,000 个插入,我得到 20,000 个 I/O。

引擎有很多内存,没有来自其他应用程序的压力。

是否可以减少这里的 I/O 数量?

这是代码的要点(为简洁起见删除了处置等)

var conn = new SqlConnection("my connection string");
conn.Open();
tran = conn.BeginTransaction();
var cmd = new SqlCommand("create table #sqltt(Context int, intValue int, stringValue varchar(100))", conn, tran))
cmd.ExecuteNonQuery();
// repeat the above sqlcmd pattern to create two indexes on the table
// then
cmd = new SqlCommand("INSERT INTO #sqltt (Context, intValue) VALUES ('-1', @intValue)", conn, tran))
var parm = cmd.CreateParameter();
parm.DbType = DbType.Int32;
parm.Direction = ParameterDirection.Input;
parm.ParameterName = "intValue";
for (var i = 0; i < HOWMANY; i++)
{
parm.Value = i;
cmd.ExecuteNonQuery();
}
tran.Commit();
conn.Close();

最佳答案

是的,通过在单个事务中批处理多个插入。每个事务都需要至少写入一个日志文件——这对于 tempdb 和任何其他数据库都是如此,因为尽管不可恢复,但 tempdb 上的操作在需要时仍然需要一致性和持久性。认为 tempdb 是“全部在内存中”或“不需要 I/O”是一种常见的误解。 SQL Server 确实有一些优化来减少 tempdb I/O(比如缓存临时表,这样它们就不需要经常重新创建)但是事务性 I/O 的基础知识仍然适用。

通过在单个事务中批处理多个插入,可以减少需要等待的顺序写入的数量。如果您想要真正最少的日志记录,请使用批量插入。顺便说一句,通过在所有插入之后而不是之前创建索引,您还将获得更好的性能(除非插入以某种方式依赖并且需要查找)。

关于sql-server - 为什么每次插入临时表一个 I/O?数据库服务器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26473686/

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