Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Программирование и базы данных (http://forum.oszone.net/forumdisplay.php?f=21)
-   -   Долгая вставка строк в таблицу базы SDF (http://forum.oszone.net/showthread.php?t=150639)

Delirium 16-09-2009 03:00 1219928

Долгая вставка строк в таблицу базы SDF
 
Имеется следующая задача:
Обойти указанный каталог, найти там все log файлы, и затолкать их в одну таблицу. В качестве источника хранения итоговой таблицы выбрана база данных SQL Server Compact (base.sdf).
Каталог обходится, файлы находятся, заливаются через OleDbDataAdapter в DataSet.
читать дальше »

Код:

public void ConnectCSV()
        {
            //Если папка с логами существует, то идем дальше
            if (Directory.Exists(Properties.Settings.Default.LOGPath) == true)
            {
                string FolderPath = Properties.Settings.Default.LOGPath + "\\";
                try
                {
                    //Проходим по всем файлам в папке
                    foreach (string fl in Directory.GetFiles(FolderPath))
                    {
                        //Если нашли LOG файл
                        if (fl.Substring(fl.Length - 3, 3) == "log")
                        {
                            //Создаем копию с расширением txt, т.к. провайдер не понимает расширения LOG
                            File.Copy(fl, fl.Replace(".log", ".txt"), true);
                            //СОхраняем в переменных имя файла и путь до папки с логами TXT
                            fileName = fl.Replace(".log", ".txt");
                            fileName = fileName.Replace(FolderPath, "");
                            dirName = FolderPath;

                            try
                            {
                                //СОздаем соединение OleDbConnection
                                cn = new OleDbConnection(@"Provider=Microsoft.Jet.OleDb.4.0;" + "Data Source=" + dirName + ";" + "Extended Properties=\"Text;HDR=NO;FMT=Delimited\"");
                                cn.ConnectionString = @"Provider=Microsoft.Jet.OleDb.4.0;" + "Data Source=" + dirName + ";" + "Extended Properties=\"Text;HDR=NO;FMT=Delimited\"";
                                using (cn)
                                {
                                    //Открываем соединение
                                    cn.Open();
                                    //Задаем SQL запрос для выборки из текущего файла.
                                    adapter = new OleDbDataAdapter("SELECT * FROM [" + fileName + "]", cn);
                                    using (adapter)
                                    {
                                        InfoLBL.Text = "  Идет обработка файлов...Пожалуйста, подождите.";
                                        //Заполняем DataSet, а именно - таблицу LOGFiles
                                        adapter.Fill(baseDataSet, "LOGTable");

                                        this.lOGTableTableAdapter.DeleteQuery();
                                       

                                      foreach (DataRow row in baseDataSet.Tables["LOGTable"].Rows)
                                        {
                                            string url = row[21].ToString();
                                            if (url.Length > 250)
                                                url = url.Substring(0, 250);

                                            lOGTableTableAdapter.InsertQuery(row[11].ToString(),
                                                row[12].ToString(),
                                                row[13].ToString(),
                                                row[14].ToString(),
                                                Convert.ToDateTime(row[15].ToString()),
                                                Convert.ToDateTime(row[16].ToString()),
                                                row[17].ToString(),
                                                Convert.ToInt32(row[18]),
                                                Convert.ToInt32(row[19].ToString()),
                                                Convert.ToInt32(row[20].ToString()),
                                                url);
                                        }

                                       
                                    }
                                }
                                //Закрываем соединение
                                cn.Close();
                            }
                                //Обработка исключений
                            catch (Exception msg_ex)
                            {
                                MessageBox.Show(msg_ex.Message);
                            }
                        }
                    }
                    InfoLBL.Text = "  Готово.";
                }
                //Обработка исключений
                catch (Exception e)
                {
                    MessageBox.Show(e.Message);
                }
            }
            else
            {
                MessageBox.Show("Не указан путь до логов");
            }
        }


Всё работает, за одним мелким недочетом: Операция вставки строк в таблицу происходит очень долго. 250 строк ~ 23 сек. А строк может быть десятки тысяч. Вставка происходит поячеечно(в коде выделено жирным).
И сам вопрос: Есть ли возможность вставить данные в таблицу быстрее?

Delirium 16-09-2009 06:33 1219951

Сам же и отвечаю на свой вопрос. Необходимо использовать BULK INSERT:

Код:

using (SqlConnection c = new SqlConnection(Properties.Settings.Default.userGateConnectionString))
                            {
                                SqlCommand command;
                                command = new SqlCommand();
                                command.CommandTimeout = 10*60*1000;
                                c.Open();
                                command.Connection = c;

                                command.CommandText = "BULK INSERT Usergate.dbo.[TableLOG]" +
                                @" FROM '" + FullFileName + "' " +
                                "WITH " +
                                "(" +
                                "FIELDTERMINATOR = ',', " +
                                "ROWTERMINATOR = '\n', CODEPAGE = 'ACP', ROWS_PER_BATCH=300, " +
                                "FIRE_TRIGGERS" +
                                ")";
                                command.ExecuteNonQuery();
                            }

где FullFileName - полное имя файла для загрузки вида "C:\temp\file.log" В таком случае скорость загрузки около 1340 записей в секунду.


Время: 19:08.

Время: 19:08.
© OSzone.net 2001-