убыстритесь sql ВСТАВЛЯЕТ

У меня есть следующий метод для вставки миллионов строк данных в таблицу (я использую 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 );
            }
        }
6
задан eKek0 31 May 2010 в 17:18
поделиться

3 ответа

Рассмотрите возможность использования bulk insert вместо этого.

SqlBulkCopy позволяет эффективно осуществлять массовую загрузить таблицу SQL Server данными из другого источника. Класс SqlBulkCopy можно использовать для записи данных только в таблицы SQL Server. Однако источник данных не ограничивается 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);
      }
} 
10
ответ дан 9 December 2019 в 20:40
поделиться

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

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

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

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

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

1
ответ дан 9 December 2019 в 20:40
поделиться

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

0
ответ дан 9 December 2019 в 20:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: