PDA

Показать полную графическую версию : Долгая вставка строк в таблицу базы SDF


Delirium
16-09-2009, 03:00
Имеется следующая задача:
Обойти указанный каталог, найти там все 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
Сам же и отвечаю на свой вопрос. Необходимо использовать 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 записей в секунду.




© OSzone.net 2001-2012