ускорить sql вставки - PullRequest
6 голосов
/ 31 мая 2010

У меня есть следующий метод для вставки миллионов строк данных в таблицу (я использую SQL 2008), и это кажется медленным, есть ли способ ускорить вставки?

Вот фрагмент кода - я использую корпоративную библиотеку MS

        public void InsertHistoricData(List<DataRow> dataRowList)
        {
            string sql = string.Format( @"INSERT INTO [MyTable] ([Date],[Open],[High],[Low],[Close],[Volumn])
                VALUES( @DateVal, @OpenVal, @High, @Low, @CloseVal, @Volumn )");

            DbCommand dbCommand = VictoriaDB.GetSqlStringCommand( sql );
            DB.AddInParameter(dbCommand, "DateVal", DbType.Date);
            DB.AddInParameter(dbCommand, "OpenVal", DbType.Currency);
            DB.AddInParameter(dbCommand, "High", DbType.Currency );
            DB.AddInParameter(dbCommand, "Low", DbType.Currency);
            DB.AddInParameter(dbCommand, "CloseVal", DbType.Currency);
            DB.AddInParameter(dbCommand, "Volumn", DbType.Int32);

            foreach (NasdaqHistoricDataRow dataRow in dataRowList)
            {
                DB.SetParameterValue( dbCommand, "DateVal", dataRow.Date );
                DB.SetParameterValue( dbCommand, "OpenVal", dataRow.Open );
                DB.SetParameterValue( dbCommand, "High", dataRow.High );
                DB.SetParameterValue( dbCommand, "Low", dataRow.Low );
                DB.SetParameterValue( dbCommand, "CloseVal", dataRow.Close );
                DB.SetParameterValue( dbCommand, "Volumn", dataRow.Volumn );

                DB.ExecuteNonQuery( dbCommand );
            }
        }

Ответы [ 4 ]

10 голосов
/ 31 мая 2010

Попробуйте вместо массовая вставка .

SqlBulkCopy позволяет эффективно группировать загрузить таблицу SQL Server с данными из другой источник. Класс SqlBulkCopy может использоваться для записи данных только в SQL Серверные столы. Тем не менее, данные источник не ограничен SQL Server; можно использовать любой источник данных, если поскольку данные могут быть загружены в Экземпляр DataTable или читать с Экземпляр IDataReader. Для этого примера файл будет содержать примерно 1000 записи, но этот код может обрабатывать большие объемы данных.

Этот пример сначала создает DataTable и заполняет его данными. Это хранится в памяти.

DataTable dt = new DataTable();
string line = null;
bool firstRow = true;

using (StreamReader sr = File.OpenText(@"c:\temp\table1.csv"))
{  
      while ((line = sr.ReadLine()) != null)
      {
            string[] data = line.Split(',');
            if (data.Length > 0)
            {
                  if (firstRow)
                  {
                        foreach (var item in data)
                        {
                              dt.Columns.Add(new DataColumn());
                        }
                        firstRow = false;
                   }

                   DataRow row = dt.NewRow();
                   row.ItemArray = data;
                   dt.Rows.Add(row);
             }
      }
}

Затем мы нажимаем DataTable на сервер за один раз.

using (SqlConnection cn = new SqlConnection(ConfigurationManager.ConnectionStrings["ConsoleApplication3.Properties.Settings.daasConnectionString"].ConnectionString))
{
      cn.Open();
      using (SqlBulkCopy copy = new SqlBulkCopy(cn))
      {
            copy.ColumnMappings.Add(0, 0);
            copy.ColumnMappings.Add(1, 1);
            copy.ColumnMappings.Add(2, 2);
            copy.ColumnMappings.Add(3, 3);
            copy.ColumnMappings.Add(4, 4);
            copy.DestinationTableName = "Censis";
            copy.WriteToServer(dt);
      }
} 
1 голос
/ 30 ноября 2010

FYI - циклический просмотр набора записей и выполнение миллиона + вставок в реляционной БД, является худшим вариантом при загрузке таблицы. Некоторые языки теперь предлагают объекты с установленными рекордами. Для быстрой работы SMINK подходит правильно, используйте BULK INSERT. Миллионы строк загружаются в считанные минуты, а не часы. На несколько порядков быстрее, чем любой другой метод.

Например, я работал над проектом электронной коммерции, который требовал обновления списка продуктов каждую ночь. 100 000 строк, вставленных в высокопроизводительную базу данных Oracle, заняли 10 часов. Если я правильно помню, максимальная скорость при вставке строки за строкой составляет приблизительно 10 записей в секунду. Болезненно медленно и совершенно не нужно. При объемной вставке - 100 тыс. Строк должны занимать менее минуты.

Надеюсь, это поможет.

1 голос
/ 31 мая 2010

Один общий совет для любой реляционной базы данных при выполнении большого количества вставок или любых изменений данных - сначала удалить все ваши вторичные индексы, а затем воссоздать их.

Почему это работает? Что касается вторичных индексов, то данные индекса будут находиться в другом месте на диске, чем данные, поэтому в лучшем случае требуется дополнительное обновление для чтения / записи для каждой записи, записанной в таблицу для каждого индекса. На самом деле это может быть гораздо хуже, поскольку время от времени база данных решает, что ей нужно выполнить более серьезную операцию реорганизации индекса.

Когда вы воссоздаете индекс в конце запуска вставки, база данных выполнит всего одну полную проверку таблицы, чтобы прочитать и обработать данные. Вы не только получите лучше организованный индекс на диске, но и общий объем требуемой работы будет меньше.

Когда это стоит делать? Это зависит от вашей базы данных, структуры индекса и других факторов (например, если у вас есть свои индексы на отдельном диске с вашими данными), но мое правило - учитывать это, если я обрабатываю более 10% записей в таблице миллиона записей или более, а затем проверьте с помощью тестовых вставок, чтобы выяснить, стоит ли это делать.

Конечно, в любой конкретной базе данных будут специальные подпрограммы массовой вставки, и вы должны также взглянуть на них.

0 голосов
/ 31 мая 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...