Почему один ввод-вывод на вставку во временную таблицу? sql-сервер

В простой тестовой программе я запускаю транзакцию, создаю таблицу #temp и два индекса, вставляю в таблицу кучу строк и фиксирую.

Наблюдая за записью ввода-вывода диспетчера задач для Sql Server, я вижу, что для каждой вставки таблицы выполняется 1 запись на диск. Это меня удивляет, потому что таблицы #temp не подлежат восстановлению, поэтому нет необходимости в записи или ведении журнала, если только нет нехватки памяти, и даже если это необходимо зарегистрировать, я ожидаю минимальное количество операций записи в журнал, а не 1 на вставку. . Вместо этого с 20 000 вставок я получаю 20 000 операций ввода-вывода.

У движка много памяти и нет давления со стороны других приложений.

Можно ли здесь уменьшить количество операций ввода-вывода?

Вот суть кода (распоряжается и т. д. удалено для краткости)

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();

person Elroy Flynn    schedule 20.10.2014    source источник
comment
Как именно вы определили количество записей? Действительно, здесь вы должны увидеть гораздо меньше операций ввода-вывода, чем запросов.   -  person usr    schedule 21.10.2014
comment
Проверьте с помощью монитора процесса и/или sys.dm_io_virtual_file_stats   -  person Martin Smith    schedule 21.10.2014
comment
Ааа, спасибо, Мартин, ты раскрыл мою ошибку. Я измерял с помощью Task Manage I/O Writes per Sql Server, но этот счетчик включает ВСЕ I/O, включая сеть. (Я знал это когда-то!) С помощью Process Monitor я вижу 27 операций записи в файл журнала общим объемом около 1,4 МБ, что в среднем составляет 75 байт на вставленную строку, что кажется разумным. Напишите как ответ, и я приму это.   -  person Elroy Flynn    schedule 21.10.2014


Ответы (2)


Да, группируя несколько вставок в одной транзакции. Каждая транзакция требует по крайней мере одной записи файла журнала — это верно для базы данных tempdb, как и для любой другой базы данных, потому что, несмотря на невозможность восстановления, операции с базой данных tempdb по-прежнему требуют согласованности и надежности в течение требуемого времени. Распространено заблуждение, что база данных tempdb «все находится в памяти» или «не требует операций ввода-вывода». В SQL Server есть некоторые оптимизации для уменьшения операций ввода-вывода tempdb (например, кэширование временных таблиц, чтобы их не нужно было повторно создавать так часто), но основы транзакционного ввода-вывода по-прежнему применимы.

Объединяя несколько вставок в одну транзакцию, вы уменьшаете количество последовательных операций записи, которые необходимо ожидать. Если вы хотите действительно минимальное ведение журнала, используйте массовые вставки. Между прочим, вы также повысите производительность, создав индексы после всех вставок, а не перед ними (если только вставки не являются зависимыми и не нуждаются в поиске).

person Jeroen Mostert    schedule 20.10.2014
comment
Проверьте мое первое предложение: это IS в одной транзакции. Таким образом, мое удивление по поводу множества операций ввода-вывода. - person Elroy Flynn; 21.10.2014
comment
Это странно. Можете ли вы уточнить свой вопрос, чтобы быть еще более явным по этому поводу (с фактическим кодом, который вставляется, если это возможно)? Обратите внимание, что остальные мои замечания остаются в силе — tempdb определенно нуждается в записи в журнал, независимо от нехватки памяти. Но что касается физической записи, вы не ожидаете 1 запись на вставку. - person Jeroen Mostert; 21.10.2014

Я измерял с помощью Task Managet «Записи ввода-вывода» для каждого сервера Sql, но этот счетчик включает ВСЕ ввод-вывод, включая сеть. См. комментарии выше, спасибо, Мартин.

person Elroy Flynn    schedule 31.10.2014