400多万条数据插入sqlexpress2008使用sqlbulkcopy如何提高速度?
我是新手,vs2008读二进制文件然后插入sql,使用sqlbulkcopy花费近20分钟,请帮看下如何提高速度2分钟以内。代码以下:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
namespace Forms
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
CreateViewItemMethodOne();
}
private void CreateViewItemMethodOne()
{
//读二进制文件数据入list
System.Collections.Specialized.StringCollection result = GetAllFiles(@"C:\jcb_sina\vipdoc\");
List<StockDayData> list = new List<StockDayData>();
for (int i = 0; i < result.Count; i++)
{
if (result[i].Substring(result[i].Length - 3) == "day")
//MessageBox.Show(result[i]);
{
string filename = result[i];
string Stockname = filename.Substring(0, filename.Length - 4);
Stockname = Stockname.Substring(Stockname.Length - 8);
FileStream fs = File.OpenRead(result[i]);
BinaryReader br = new BinaryReader(fs);
int days = (int)fs.Length / 32;
//List<StockDayData> list = new List<StockDayData>();
for (int j = 0; j < days; j++)
{
StockDayData item = new StockDayData();
//item.DataDate =DateTime.Parse(new string(br.ReadChars(8)));
int date = br.ReadInt32();
int year = date / 10000;
int month = int.Parse(date.ToString().Substring(4, 2));
int day = int.Parse(date.ToString().Substring(6, 2));
//item.DataDate = new DateTime(year, month, day);
int open = br.ReadInt32();
int high = br.ReadInt32();
int low = br.ReadInt32();
int close = br.ReadInt32();
Single amount = br.ReadSingle();
//Int32 amount = br.ReadInt32();
decimal am = Convert.ToDecimal(amount);
long amstr = Convert.ToInt64(amount);
int vol = br.ReadInt32();
int preclose = br.ReadInt32();
//Decimal open = Convert.ToDecimal(br.ReadSingle());
item.Stockname = Stockname;
item.Date = date;
item.Open = Convert.ToDecimal(open / 100m);
item.High = Convert.ToDecimal(high / 100m);
item.Low = Convert.ToDecimal(low / 100m);
item.Close = Convert.ToDecimal(close / 100m);
item.Amount = amstr;
item.Vol = vol;
item.PreClose = Convert.ToDecimal(preclose / 100m);
list.Add(item);
}
br.Close();
fs.Close();
this.dataGridView1.DataSource = list;//dataGridView显示数据快2分钟
}
}
Inert2DBBySqlBulkCopy_TB_StockDayInfo(list);//插入sql,这里是不是有问题?
}
public static void Inert2DBBySqlBulkCopy_TB_StockDayInfo(List<StockDayData> list)//插入sql方法
{
DataTable dt = new DataTable();
dt.Columns.Add("Stockname", System.Type.GetType("System.String"));
dt.Columns.Add("Date", System.Type.GetType("System.Int32"));
dt.Columns.Add("Open", System.Type.GetType("System.Decimal"));
dt.Columns.Add("High", System.Type.GetType("System.Decimal"));
dt.Columns.Add("Low", System.Type.GetType("System.Decimal"));
dt.Columns.Add("Close", System.Type.GetType("System.Decimal"));
dt.Columns.Add("Vol", System.Type.GetType("System.Decimal"));
dt.Columns.Add("Amount", System.Type.GetType("System.Decimal"));
dt.Columns.Add("PreClose", System.Type.GetType("System.Decimal"));
foreach (var item in list)
{
DataRow dr = dt.NewRow();
dr["Stockname"] = item.Stockname;
dr["Date"] = item.Date.ToString();
dr["Open"] = item.Open;
dr["High"] = item.High;
dr["Low"] = item.Low;
dr["Close"] = item.Close;
dr["Vol"] = item.Vol;
dr["Amount"] = item.Amount;
dr["PreClose"] = item.PreClose;
dt.Rows.Add(dr);
}
SqlConnection conn = new SqlConnection();
try
{
SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder();
builder.DataSource = ".\\SQLExpress";
builder.InitialCatalog = "StockData";
builder.IntegratedSecurity = true;
conn.ConnectionString = builder.ConnectionString;
conn.Open();
using (SqlBulkCopy sqlBulkCopy = new SqlBulkCopy(conn))//这里是不是需要多线程,如何改代码?
{
sqlBulkCopy.ColumnMappings.Add(0, "Stockname");
sqlBulkCopy.ColumnMappings.Add(1, "Date");
sqlBulkCopy.ColumnMappings.Add(2, "Open");
sqlBulkCopy.ColumnMappings.Add(3, "High");
sqlBulkCopy.ColumnMappings.Add(4, "Low");
sqlBulkCopy.ColumnMappings.Add(5, "Close");
sqlBulkCopy.ColumnMappings.Add(6, "Vol");
sqlBulkCopy.ColumnMappings.Add(7, "Amount");
sqlBulkCopy.ColumnMappings.Add(8, "PreClose");
sqlBulkCopy.BatchSize = 100000;
sqlBulkCopy.BulkCopyTimeout = 60;
sqlBulkCopy.DestinationTableName = "TB_StockDayInfo";
sqlBulkCopy.WriteToServer(dt);
}
}
catch (SqlException e)
{
Console.WriteLine("Error accessing the database: {0}", e.Message);
}
finally
{
conn.Close();
}
}
public class StockDayData//数据struct
{
private string mStockname;
public string Stockname
{
get { return mStockname; }
set { mStockname = value; }
}
private int mDate;
public int Date
{
get { return mDate; }
set { mDate = value; }
}
private decimal mOpen;
public decimal Open
{
get { return mOpen; }
set { mOpen = value; }
}
private decimal mHigh;
public decimal High
{
get { return mHigh; }
set { mHigh = value; }
}
private decimal mLow;
public decimal Low
{
get { return mLow; }
set { mLow = value; }
}
private decimal mClose;
public decimal Close
{
get { return mClose; }
set { mClose = value; }
}
private long mAmount;
public long Amount
{
get { return mAmount; }
set { mAmount = value; }
}
private int mVol;
public int Vol
{
get { return mVol; }
set { mVol = value; }
}
private decimal mPreClose;
public decimal PreClose
{
get { return mPreClose; }
set { mPreClose = value; }
}
}
public void GetAllFiles(string parentDir, System.Collections.Specialized.StringCollection result)
{
string[] dir = System.IO.Directory.GetDirectories(parentDir);
for (int i = 0; i < dir.Length; i++)
GetAllFiles(dir[i], result);
string[] file = System.IO.Directory.GetFiles(parentDir);
for (int i = 0; i < file.Length; i++)
result.Add(file[i]);
}
public System.Collections.Specialized.StringCollection GetAllFiles(string rootdir)
{
System.Collections.Specialized.StringCollection result = new System.Collections.Specialized.StringCollection();
GetAllFiles(rootdir, result);
return result;
}
}
}