2012-05-02 3 views
0

У меня есть набор из 30 файлов. Я просматриваю эти файлы, и для каждого из них я вставляю 1529 строк, которые имеют приблизительно 30 столбцов и 219487 строк, которые содержат приблизительно 6 столбцов.SQL-сервер замедляется, какова может быть причина/способы улучшения?

Я делаю это в C# и вставляю через datatable (см. Внизу). Я сгруппировал вставки в 1300 строк на каждую партию для 1529 строк (30 столбцов) и 50000 за партию для 219 487 строк (6 столбцов).

При вставке каждой партии нет многопоточности - все последовательно (по крайней мере, в моем коде). Я не запускаю следующий файл, пока моя строка кода не завершит вставку предыдущего файла.

Учитывая это, я ожидал бы, что SQL-сервер завершит каждый файл в постоянное время (файлы очень похожи, это всегда вставки 1529 и 219487).

Однако время, затраченное на каждую вставку SQL в файл, увеличивается линейно - от 9 секунд в первом файле до 50 секунд в направлении 30-го файла. Я отделил процессорное время от принятого SQL-времени и в начале занимает 0,000033 секунды, чтобы вставить одну из шести столбцов. К концу, для более поздних файлов, для данных с 6 столбцами, время составляет 0,000228. Другими словами, время, затрачиваемое на вставку данных из 219 487 строк (6 столбцов), увеличилось примерно в 7 раз?

Я уменьшил размер партии до 20000, и это не имело значения. Раньше я полагал, что уменьшил его до 5000 и 10000, и это все равно не имело никакого значения. Я не очень разбираюсь в базовой архитектуре SQL, поэтому немного теряюсь.

Мне кажется, что я перегружаю SQL-сервер. Однако, было ли впечатление, что это делается последовательно, а не дает задания на SQL-сервер? Его возможные запросы SQL порождаются потоками, однако я уменьшаю размер партии до 100 (см. Ниже), и это все еще не помогло. Общее время для завершения было больше, но оно по-прежнему увеличивалось линейно в каждом файле.

Я уменьшил размер партии до 100 (просто чтобы сервер не перегружался), и я все еще вижу линейно увеличивающиеся времена ??

На протяжении всего времени я имел в виду время, затраченное на вставку SQL, а не комбинированное время SQL + CPU на файл.

Возможно, будет невозможно точно сообщить, что происходит, но могу ли я найти несколько советов и вещей, которые обязательно избегают, чтобы лучше всего исправить это?

Моя вставка SQL кода (так называемый в каждой вставки пакетном) является:

private static void WriteResultsToDatabase(string tableName, DataTable tableToWrite) 
     { 

      using (SqlConnection connection = 
        new SqlConnection(connectionString)) 
      { 
       SqlBulkCopy bulkCopy = 
        new SqlBulkCopy 
        (
        connection, 
        SqlBulkCopyOptions.TableLock | 
        SqlBulkCopyOptions.FireTriggers | 
        SqlBulkCopyOptions.UseInternalTransaction, 
        null 
        ); 

       bulkCopy.DestinationTableName = tableName; 
       for (int i = 0; i < tableToWrite.Columns.Count; i++) 
        bulkCopy.ColumnMappings.Add(tableToWrite.Columns[i].ColumnName, tableToWrite.Columns[i].ColumnName); 
       try 
       { 
        connection.Open(); 

        bulkCopy.WriteToServer(tableToWrite); 

       } 
       finally 
       { 
        connection.Close(); 
       } 
      } 
     } 

ответ

0

Он чувствует ко мне, что я перегрузить SQL сервер

Да, это хорошая причина - особенно, и только если ваш сервер sql работает на мобильном телефоне или имеет жалкий диск конечного пользователя. В противном случае - нет.

Я мало что знаю о базовой архитектуре SQL, поэтому я немного потерялся.

Узнать больше. Получите планы запросов. Требуются таблицы + индексы. Уникальные ограничения? Есть ли уникальное ограничение без индекса? Это заставляет сканировать таблицу все время.

Также стоит: Вставить во временную таблицу, созданную из исходной таблицы (тривиально), затем скопировать данные в одном выражении.

от 9 секунд на первый файл

Для 220.000 строк, много уже. Я предлагаю проверить сервер, насколько он занят во время ваших операций и все ограничения в таблице для соответствия индексов. И триггеры;)

+0

Получить план запроса для простой инструкции вставки? – mezamorphic

+0

Фактически - нет. Но если есть триггеры, они появляются в выполненном плане, вы знаете. Он может выглядеть как простая вставка, но запускать тонну обработки. Уникальные ограничения, вызывающие выбор и т. Д. – TomTom

+0

Когда я сказал SQL-архитектуру, я имел в виду, как SQL работает под капотом, а не с конкретным планом запроса :) – mezamorphic

0

Это может быть любое количество вещей, но очевидные для меня будет выглядеть следующим образом:

  1. У вас есть кластерный ключ на столах, и вы не вставляя записи в порядке этого ключа. Для каждой операции вставки, , перед выполнением задачи необходимо будет физически изменить порядок записей.
  2. У вас есть несколько указателей/внешних ключей с проверками на таблицах, , поэтому с каждой итерацией вы добавляете все больше и больше информации в .
  3. Ваши триггеры не используются эффективно или не сконструированы эффективно, в том смысле, что он должен работать против всей таблицы вместо недавно вставленных данных.
  4. Вы создали массовую транзакцию, но что-то мешает серверу базы данных рассматривать его как один. Убедитесь, что монитор активности видит это как массовую операцию.
  5. Вы разворачиваете свою базу данных в процентах вместо фиксированной суммы; для каждого роста потребуется больше времени, чтобы выделить больше .

Это все проблемы, с которыми я столкнулся раньше; любая из них или любая комбинация могут создавать симптомы, которые вы описываете.

Смежные вопросы