在一个简单的测试程序中,我启动一个事务,创建一个#temp表和两个索引,在表中插入一堆行,然后提交。
观察任务管理器I / O写入Sql Server,我看到每个表插入有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();
答案 0 :(得分:1)
是的,通过在单个事务中批量处理多个插入。每个事务都需要至少写入一个日志文件 - 对于tempdb来说,这适用于任何其他数据库,因为尽管不可恢复,但tempdb上的操作仍然需要在他们需要的时间内保持一致性和持久性。这是一个常见的误解,即tempdb是&#34;所有内存和#34;或&#34;不需要I / O&#34;。 SQL Server确实有一些优化来减少tempdb I / O(比如缓存临时表,因此它们不需要经常重新创建),但事务I / O的基础知识仍然适用。
通过在单个事务中批量处理多个插入,可以减少需要等待的顺序写入次数。如果您想要真正的最小日志记录,请使用批量插入顺便说一句,通过在所有插入之后创建索引,而不是之前(除非插入以某种方式依赖并且需要查找),您也将获得更好的性能。
答案 1 :(得分:0)
我正在使用任务管理器测量&#34; I / O写入#34;每个Sql Server,但该计数器包括所有I / O,包括网络。见上面的评论,谢谢马丁。