
工作中有段时间常常涉及到不同版本的数据库间导出导入数据的问题索性整理一下并简单比较下性能有所遗漏的方法也欢迎讨论、补充。00.建立测试环境01.使用SQL Server Import and Export Tool02.使用Generate Scripts03.使用BCP04.使用SqlBulkCopy05.使用Linked Server进行数据迁移06.使用RedGate的SQL Data Compare07.结果对比可以先看下测试的结果00.建立测试环境建立一个测试的环境一个数据源数据库版本为SQL Server 2008一个目标数据库版本为SQL Server 2000。实验环境如下图所示源数据库使用语句生成了100万的测试数据。建立测试表并生成100万的测试数据1IFOBJECT_ID(DEMOTABLE)ISNOTNULL2DROPTABLEDEMOTABLE3GO4CREATETABLEDEMOTABLE5(6COL1VARCHAR(50) ,7COL2VARCHAR(50) ,8COL3VARCHAR(50)9)10INSERTINTODEMOTABLE11SELECTTOP100000012NEWID() ,13NEWID() ,14NEWID()15FROMMASTER..SPT_VALUES T116INNERJOINMASTER..SPT_VALUES T2ON1117INNERJOINMASTER..SPT_VALUES T3ON1101.使用SQL Server Import and Export Tool使用SQL Server Import and Export Tool进行数据的导出也可以在目标数据库端使用Import进行导入这部分套件也是SSIS的一部分。在源数据库上右键选择Task - Export Data分别填写源数据库和目标数据库的连接信息。选择“copy data from one or more tables or views”选择需要导数据的表并且可以编辑列的Mapping关系。可以选择立即执行或者存储为SSIS的包用于执行计划等其他用途。这里我们选择立即执行。注意导入的时候如果遇到如下的错误Error 0xc02020f4: Data Flow Task: The column Tel cannot be processed because more than one code page (936 and 1252) are specified for it.(SQL Server Import and Export Wizard)是因为两边的数据库的Collation设置不一样造成的需要设置同样的Collation。用时约1分30秒02.使用Generate Scripts生成脚本在源数据库上右键选择Task - Geneate Scripts...配置相关信息注意选择数据库的版本并将Script Data设置成True。这里需要注意因为有100万的数据所以导出的SQL文件就有400多M所以用SQL Server Management Studio是打不开的。所以只能使用sqlcmd执行。sqlcmd语句1C:\sqlcmd-i export.sql-d ExportDataDemo_Destination-s192.168.21.165-U sa-P1234567890用时约28分钟03.使用BCP进行导出导入在尝试了前面两个效率低下的工具之后我们终于开始尝试下SQL Server中专门用于导数据的工具BCP。关于BCP的详细用法可以参见MSDN的帮助文档。我们先使用BCP导出数据。-U和-P后面分别为数据库的用户名和密码。我们可以看到100万的数据导出仅用了1.8秒。现在我们再使用BCP进行导入。执行后发现导入数据使用了20.8秒还是很快的。用时1.872秒20.810秒22.682秒04.使用SqlBulkCopy.NET Framework 2.0中增加的SqlBulkCopy类可以进行高效的数据迁移动作这也为代码实现数据迁移提供了接口。并且SqlBulkCopy类提供了修改字段Mapping关系的方法ColumnMappings。使用SqlBulkCopy类进行数据迁移1usingSystem;2usingSystem.Data;3usingSystem.Data.SqlClient;45namespaceBulkInsert6{7staticclassProgram8{9staticvoidMain()10{11DateTime dateTimeStart DateTime.Now;12Console.WriteLine(Start Insert: dateTimeStart.ToString(HH:mm:ss fff));13//导入导出的数据库连接14SqlConnection connectionDestination newSqlConnection(Server .; User IDdatascan; PasswordDTSbsd7188228; Initial CataLogExportDataDemo_Destination;);15SqlConnection connectionSource newSqlConnection(Server .; User IDdatascan; PasswordDTSbsd7188228; Initial CataLogExportDataDemo_Source;);1617//实例化一个SqlBulkCopy18varbulker newSqlBulkCopy(connectionDestination) { DestinationTableName DEMOTABLE, BulkCopyTimeout 600};1920//获取源数据库的数据21SqlCommand sqlcmd newSqlCommand(SELECT * FROM DEMOTABLE, connectionSource);22SqlDataAdapter sqlDataAdapter newSqlDataAdapter(sqlcmd);23DataTable dataTableSource newDataTable();24sqlDataAdapter.Fill(dataTableSource);2526//可以重新定义字段的Mapping关系27//SqlBulkCopyColumnMapping sqlBulkCopyColumnMapping new SqlBulkCopyColumnMapping(COL1, NEW_COL1);28//bulker.ColumnMappings.Add(sqlBulkCopyColumnMapping);29connectionDestination.Open();30bulker.WriteToServer(dataTableSource);31bulker.Close();32DateTime dateTimeEnd DateTime.Now;33Console.WriteLine(Insert Ending: dateTimeEnd.ToString(HH:mm:ss fff));34}35}36}执行后用时14.8秒05.使用Linked Server进行数据迁移先在源数据库上对目标数据库建立Linked Server或者反过来也行。建立Linked Server1EXECsp_addlinkedserverserverLinkedServerToDemo,2srvproductExport Data Testing,providerMSDASQL,3provstrDRIVER{SQL Server};SERVER192.168.21.165;UIDsa;PWDpassword;是用INSERT INTO...SELECT...进行导入1DECLAREbegin_dateDATETIME2DECLAREend_dateDATETIME3SELECTbegin_dateGETDATE()45INSERTINTOLinkedServerToDemo.ExportDataDemo_Destination.dbo.DEMOTABLE6SELECT*7FROMExportDataDemo_Source.dbo.DEMOTABLE89SELECTend_dateGETDATE()10SELECTDATEDIFF(ms,begin_date,end_date)AS用时/毫秒执行用时用时7.97分钟06.使用RedGate的SQL Data Compare进行数据迁移第三方的工具有数据库结构比较的工具SQL Compare和数据比较工具SQL Data Compare。执行因为也是生成INSERT的SQL执行的所以就不做过多比较了上面已经测试过了。07.结果对比因为这里测试的环境有网络和表结构的特殊情况不能说明所有情况下效能的差异但是也可作为参考之用。下面给出比较结果。