2013-03-01 90 views
2

我正在开发一个Windows应用程序,其中我上传一个文本文件。 在该文本文件中有5000行,其中用逗号[,]分隔数据。 我在后端使用oledb连接[MS Access]。 我正在从文件中获取逗号分隔的数据并将其插入到数据库中。速度的数据输入数据库

但正如我观察到的那样,数据几乎是15000-16000条记录。 插入时每秒钟会花费近7条记录。

我想提高这个速度。

这是否取决于我们在后端用作数据库的内容?

sql server 2005可以提高速度而不是MS Access吗?

请帮我。

请参阅代码:

string file = openFileDialog1.FileName; 
StreamReader inputData = new StreamReader(file); 
while ((line = inputData.ReadLine()) != null) 
{ 
    subLine = line.Split(','); 

    /*Taking Unique ID from tradefile table*/ 
    int ID=0; 
    try 
    { 
     da=new OleDbDataAdapter("select max(ID) from tradeFile",con); 
     DataSet ds=new DataSet(); 
     da.Fill(ds); 

     for (int i = 0; i < ds.Tables[0].Rows.Count; i++) 
     { 
      if (ds.Tables[0].Rows[i][0].ToString() == "") 
      { 
      } 
      else 
      { 
       ID = int.Parse(ds.Tables[0].Rows[i][0].ToString()); 
       ID++; 
      } 
     } 
    } 
    catch(Exception ex) 
    { 
     MessageBox.Show(ex.Message); 
    } 


    try 
    { 
     string unknown="unknown Fileld"; 
     con.Open(); 
     // int j=subLine.Length; 
     //for(int i=0;i<subLine.Length;i++) 
     { 
      int i = 0; 
      //int j=subLine.Length; 
      //int index=subLine.Length-j; 
      cmd=new OleDbCommand(
       "insert into tradeFile values('"+ID+"','"+ 
       subLine[i].ToString()+"','"+subLine[++i].ToString()+"','"+ 
       subLine[++i].ToString()+"','"+subLine[++i].ToString()+"','"+ 
       subLine[++i].ToString()+"','"+subLine[++i].ToString()+"','"+ 
       subLine[++i].ToString()+"','"+subLine[++i].ToString()+"','"+ 
       subLine[++i].ToString()+"','"+subLine[++i].ToString()+"','"+ 
       subLine[++i].ToString()+"','"+subLine[++i].ToString()+"','"+ 
       subLine[++i].ToString()+"','"+subLine[++i].ToString()+"','"+ 
       subLine[++i].ToString()+"','"+subLine[++i].ToString()+"','"+ 
       subLine[++i].ToString()+"','"+subLine[++i].ToString()+"','"+ 
       subLine[++i].ToString()+"','"+subLine[++i].ToString()+"','"+ 
       subLine[++i].ToString()+"','"+subLine[++i].ToString()+"','"+ 
       subLine[++i].ToString()+"','"+subLine[++i].ToString()+"','"+ 
       unknown+"')",con); 
      cmd.ExecuteNonQuery(); 

     } 
    } 
    catch (Exception ex) 
    { 
     MessageBox.Show(ex.Message); 
    } 
    finally 
    { 
     con.Close(); 
    } 
    //counter++; 
} 
+0

您是使用ADO.NET插入的吗?或者你使用某种类型的O/R映射? – Groo 2013-03-01 11:15:51

+0

@格罗奥先生,ADO.NET – Freelancer 2013-03-01 11:17:47

+0

然后你应该使用批处理,或者更好的'SQLBulkCopy'。我在下面添加了一个答案。 – Groo 2013-03-01 11:38:10

回答

3

您可以一次通过insertint多行提高速度。据我所知sql-server允许在一个查询中插入1000行,至少是5-6个查询而不是5-6个查询。不知道有多少行可以处理ms访问。此外,插入速度当然取决于RDBMS

UPD:

奇怪的,你做额外的查询来获取新的ID为表。你真的应该使用自动增量字段,这是第一个。 二:你的结果插入查询应该是这样的:

insert into tradeFile (field1, field2 ... fieldN) 
values (f1value1, f2value1...fNvalue1), (f1value2, f2value2...fNvalu2) etc. 

;第三 - 你需要记住,你不能同时插入多N(例如1000 SQL Server)的值,因此你的代码可能如下:

string file = openFileDialog1.FileName; 
StreamReader inputData = new StreamReader(file); 
int values = 0; 
const int maxValuesPerInsert = 1000; 
string insertQuery = string.empty; 
while ((line = inputData.ReadLine()) != null) 
{ 
    subLine = line.Split(','); 
    /*do some work to extract values (lemme call em value1, value2...)*/ 
    if (values < maxValuesPerInsert - 1) 
    { 
     insertQuery += string.format("({0}, {1}, {2}),", value1, value2, value3); 
     values++; 
    } 
    else 
    { 
     insertQuery += string.format("({0}, {1}, {2})", value1, value2, value3); //just to get rid of last comma    
     var query = string.format("insert into tradeFile (field1, field2, field 3) values {0}", insertQuery); 
     /*do your db query*/ 
     insertQuery = string.empty; 
     values = 0; 
    } 

} 
+0

先生,关于一次添加多行>>>请在编辑的问题中查看我的代码。我已经在while循环中插入查询,以获取记录并相应地插入它。 – Freelancer 2013-03-01 11:22:17

+0

更新我的答案,写在记事本代码,所以可能有一些错误:)但整个algorythm接近工作 – Sergio 2013-03-01 11:38:09

+0

通过串联字符串创建INSERT字符串被认为是不好的做法,使应用程序容易发生SQL注入攻击(在此如果数据是从文件中加载的,只是为了强调这不是一种常见的方式)。另外,如果你已经使用'Split'来获得一串字符串,那么'StringBuilder'可能是一个更好的选择来简单地追加所有的值。而且,值得一提的是,只有SQL Server 2008和更新版本才能使用一个语句插入多行(“行构建”)。 – Groo 2013-03-01 11:54:16

0

是的,SQL服务器比MSACCESS更快更可靠。

当您使用具有多个连接的当代访问或当您有大量工作量时,避免使用大数据库的访问权限(几千条记录可能对访问很大)。

SQL Server Express的可能就够了(而且是免费的,见局限性这里:http://social.msdn.microsoft.com/Forums/en-US/sqldensetup/thread/0e781eb4-1c27-4777-9bd8-bc9e1ae3e803/

Antoher“变通方法”可以使用在一个查询中多次插入或使用BULK INSERT(即我不知道是支持访问)

+0

先生,关于添加>>>一次有多行>>>请在编辑的问题中查看我的代码。我已经在while循环中插入查询,以获取记录并相应地插入它。 – Freelancer 2013-03-01 11:25:14

0

当然,使用MsSQL服务器代替MS Access会提高速度。 也正如我认为你正在为每行1查询。您必须在每个查询中添加几行。这会增加速度。

你用什么算法来分割文本文件中的数据?

+0

先生请通过我编辑的问题,我已经把它的代码 – Freelancer 2013-03-01 11:19:16

+0

因为我在插入查询while循环[所以读取数据并相应地插入] – Freelancer 2013-03-01 11:20:04

0

我想提高这个速度。

您应该查看ADO.NET batching

基本上,你创建一个DataAdapter(即,如果你选择为SQL Server),在那里你指定你的更新,插入和删除命令,然后将DataAdapter.UpdateBatchSize属性设置为大于1的值(例如尝试1000并看看会发生什么)。

具有适度的硬件,你应该能够插入每秒〜10,000行,但我会尝试一些不同的批量大小和轮廓

sql server 2005可以提高速度而不是MS Access吗?

是的,如果您需要使用更大的数据集,您应该考虑切换到SQL Server。不过,不需要使用2005年版本; SQL Server 2012 Express是2012年的免费版本。

如果您确实有大量行(例如100,000行)一次插入,您还可以考虑使用SQLBulkCopySQLBulkCopy特别适用于在同一台服务器上的不同表之间复制数据的情况。