我有连接到Sql Server数据库的Handheld设备,读取Sql server数据并将其放在设备上的SQL Compact数据库中。这是我的代码:
public void InsertData() // Function insert data into SQL commapct database
{
dt = new DataTable();
dt = SqlServer_GetData_dt("Select id_price, price, id_item from prices", SqlCeConnection); // get data form sql server
if (dt.Rows.Count > 0)
{
for (int i = 0; i < dt.Rows.Count; i++)
{
string sql = "";
sql = "insert into prices" +
" ( id_prices, price,id_item) values('"
+ dt.Rows[i]["id_price"].ToString().Trim() + "', '"
+ dt.Rows[i]["price"].ToString().Trim() + "', '"
+ dt.Rows[i]["id_item"].ToString().Trim() + "')";
obj.SqlCE_WriteData_bit(sql, connection.ConnectionString);//insert into sql compact
}
}
}
public DataTable SqlServer_GetData_dt(string query, string conn)
{
try
{
DataTable dt = new DataTable();
string SqlCeConnection = conn;
SqlConnection sqlConnection = new SqlConnection(SqlCeConnection);
sqlConnection.Open();
{
SqlDataReader darSQLServer;
SqlCommand cmdCESQLServer = new SqlCommand();
cmdCESQLServer.Connection = sqlConnection;
cmdCESQLServer.CommandType = CommandType.Text;
cmdCESQLServer.CommandText = query;
darSQLServer = cmdCESQLServer.ExecuteReader();
dt.Load(darSQLServer);
sqlConnection.Close();
}
return dt;
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
DataTable dt = new DataTable();
return dt;
}
}
public object SqlCE_WriteData_bit(string query, string conn)
{
try
{
string SqlCeConnection = conn;
SqlCeConnection sqlConnection = new SqlCeConnection(SqlCeConnection);
if (sqlConnection.State == ConnectionState.Closed)
{
sqlConnection.Open();
}
SqlCeCommand cmdCESQLServer = new SqlCeCommand();
cmdCESQLServer.Connection = sqlConnection;
cmdCESQLServer.CommandType = CommandType.Text;
cmdCESQLServer.CommandText = query;
object i = cmdCESQLServer.ExecuteScalar();
sqlConnection.Close();
return i;
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
return 0;
}
}
这一切都很好,但问题是所有这些工作都很慢。我有20 000行需要插入到SQL压缩数据库中。
有没有办法加快插入速度?
感谢。
答案 0 :(得分:1)
除了每次调用对Connection的明显不良使用外,您还可以通过完全取消查询处理器来大大改善。这意味着不要使用SQL。而是使用TableDirect
和SqlCeResultset
打开目标表。迭代源数据(一个DataTable是一个坏主意,但这完全不同)并使用一系列CreateRecord
,SetValues
和Insert
。
A pretty good example can be found here(虽然我再次使用SetValues
来设置整行,而不是每个字段。
答案 1 :(得分:0)
重复使用您的连接,不要为每个INSERT
语句创建新连接。
不是将连接字符串传递给SqlCE_WriteData_bit
方法,而是在InsertData
方法中创建一次连接,并将连接对象传递给SqlCE_WriteData_bit
。
答案 2 :(得分:0)
将所有数据放入DataTable
,然后使用SqlCeDataAdapter
通过一次调用Update
保存所有数据。你可能不得不摆弄UpdateBatchSize
以获得最佳表现。
仔细观察,我发现你已经有了DataTable
。因此,自己循环是荒谬的。请注意,正如您所拥有的那样,每个RowState
的{{1}}将为DataRow
,因此不会插入它们。我认为您可以致电Unchanged
,以便将所有DataTable.Load
值保留为RowState
,但如果没有,则改为使用Added
,将SqlDataAdapter
设为AcceptChangesDuringFill
并致电false
。
答案 3 :(得分:0)
有没有办法加快插入速度?
是的,但当我们谈论插入20k行时,它可能不会“足够快”。
我可以看到的问题是,您正在为SqlServer_GetData_dt
检索的每一行打开一个连接,也就是说,您打开一个连接以插入数据20k次...打开一个连接是一个昂贵的交易。您应该使用StringBuilder
对象构建整个查询,然后在一个批处理中执行所有insert语句。
这会带来一些性能提升,但不要指望它能解决你的问题,插入20k行仍然需要一些时间,特别是如果索引需要重建。我的建议是,你应该彻底分析你的要求,并对你如何处理它有点聪明。选项包括:
insert
进程,并仅在预填充完成后访问数据