如何通过C#或直接从数据库将SQL Server批量记录插入SQLite表以提速
高效批量迁移SQL Server数据到SQLite的方案
逐条插入之所以慢,核心原因是每条记录都要单独触发事务、IO操作,累积起来开销巨大。下面给你两种针对性的优化方案,按需选择:
方案一:C# 程序化批量插入(适合实时/动态同步场景)
这个方案通过显式事务+批量参数化插入来减少IO次数,同时调整SQLite的写入配置来大幅提升性能。
步骤1:从SQL Server获取数据
先把存储过程的结果读取到DataTable(也可用List<T>,DataTable适配性更强):
DataTable GetSqlServerData() { var dataTable = new DataTable(); string sqlServerConnStr = "Server=你的实例名;Database=你的库名;User Id=账号;Password=密码;"; using (var conn = new SqlConnection(sqlServerConnStr)) { conn.Open(); using (var cmd = new SqlCommand("EXEC dbo.你的存储过程名", conn)) { using (var adapter = new SqlDataAdapter(cmd)) { adapter.Fill(dataTable); } } } return dataTable; }
步骤2:批量插入SQLite
关键优化点:
- 开启显式事务,每批次提交一次(避免每条记录单独提交的开销)
- 复用参数化查询,既防止SQL注入又提升执行效率
- 调整SQLite连接字符串的同步模式和日志模式,这是写入提速的核心
void BulkInsertToSqlite(DataTable data) { // 优化后的SQLite连接字符串:关闭强同步+启用WAL日志,写入速度提升数倍 string sqliteConnStr = "Data Source=你的SQLite数据库.db;Synchronous=NORMAL;Journal Mode=WAL;"; using (var conn = new SQLiteConnection(sqliteConnStr)) { conn.Open(); const int batchSize = 1000; // 每批次插入1000条,可根据内存情况调整 int recordCount = 0; // 开启事务 using (var transaction = conn.BeginTransaction()) { // 构造插入语句,替换成你的实际列名 string insertSql = @"INSERT INTO sqlite_table (列1, 列2, 列3, 列4) VALUES (@Col1, @Col2, @Col3, @Col4)"; using (var cmd = new SQLiteCommand(insertSql, conn, transaction)) { // 预先定义参数(复用参数,避免重复创建开销) cmd.Parameters.Add("@Col1", DbType.String); cmd.Parameters.Add("@Col2", DbType.Int32); cmd.Parameters.Add("@Col3", DbType.DateTime); cmd.Parameters.Add("@Col4", DbType.Decimal); foreach (DataRow row in data.Rows) { // 给参数赋值,处理空值避免报错 cmd.Parameters["@Col1"].Value = row["SQLServer列1"] ?? DBNull.Value; cmd.Parameters["@Col2"].Value = row["SQLServer列2"] ?? DBNull.Value; cmd.Parameters["@Col3"].Value = row["SQLServer列3"] ?? DBNull.Value; cmd.Parameters["@Col4"].Value = row["SQLServer列4"] ?? DBNull.Value; cmd.ExecuteNonQuery(); recordCount++; // 每批次提交一次,释放中间资源 if (recordCount % batchSize == 0) { transaction.Commit(); transaction.Dispose(); // 重新开启事务 transaction = conn.BeginTransaction(); cmd.Transaction = transaction; } } // 提交剩余的未批次记录 transaction.Commit(); } } } }
调用方式
var sqlServerData = GetSqlServerData(); BulkInsertToSqlite(sqlServerData);
方案二:SQL Server导出+SQLite导入(适合一次性/定时迁移)
如果不需要程序化实时同步,用命令行工具导出+导入是性能最高的方式,完全绕开逐行处理的开销。
步骤1:用BCP导出SQL Server数据到CSV
打开命令提示符,执行BCP命令(替换成你的实际参数):
bcp "EXEC 你的数据库名.dbo.你的存储过程名" queryout "C:\temp\data_export.csv" -S 你的SQLServer实例名 -U 用户名 -P 密码 -c -t, -r\n
参数说明:
-c:用纯文本格式导出,兼容性强-t,:用逗号作为列分隔符-r\n:用换行作为行分隔符
步骤2:用SQLite命令行导入CSV
打开SQLite命令行工具,执行以下命令:
-- 连接到你的SQLite数据库 sqlite3 你的SQLite数据库.db -- 设置CSV模式 .mode csv -- 如果CSV列顺序和目标表完全一致,直接导入 .import C:\temp\data_export.csv sqlite_table -- 如果列顺序不一致,先导入临时表再转存 CREATE TABLE temp_import (列1 TEXT, 列2 INTEGER, 列3 DATETIME); .import C:\temp\data_export.csv temp_import INSERT INTO sqlite_table (目标列1, 目标列2, 目标列3) SELECT 列1, 列2, 列3 FROM temp_import; DROP TABLE temp_import;
额外优化提示
- SQLite配置必须调整:一定要在连接字符串中加上
Synchronous=NORMAL;Journal Mode=WAL;,这能把写入速度提升3-5倍 - 批次大小灵活调整:方案一中的
batchSize可以根据内存情况调整,1000-2000条是比较均衡的选择 - 空值处理:代码中必须处理
DBNull.Value,否则插入时会抛出类型不匹配的错误
内容的提问来源于stack exchange,提问作者Rajesh
相关产品推荐
相关产品推荐

