Wou*_*ter 6 java sql-server performance bulkinsert sql-server-2014
在寻找从JAVA到SQL Server获取数据的最快方法的过程中,我注意到我能想到的最快的JAVA方法,仍然比使用BULK INSERT慢12倍.
我的数据是从JAVA中生成的,而BULK INSERT只支持从文本文件中读取数据,因此除非我将数据输出到临时文本文件,否则不能使用BULK INSERT.反过来,这当然会成为巨大的性能打击.
从JAVA插入时,插入速度约为每秒2500行.即使当我测量时间后的该则ExecuteBatch for循环,和之前.因此,"创建"内存中的数据不是瓶颈.
使用BATCH INSERT插入时,插入速度约为每秒30000行.
两个测试都在服务器上完成.所以网络也不是瓶颈.有关为什么BATCH INSERT更快的任何线索?而且,如果在JAVA内可以获得相同的性能?
这只是一个需要加载一次的大数据集.因此可以临时禁用任何类型的日志记录(已经尝试过简单的日志记录),禁用索引(表没有),锁定,等等,...
到目前为止我的测试设置
数据库:
CREATE TABLE TestTable
( Col1 varchar(50)
, Col2 int);
Run Code Online (Sandbox Code Playgroud)
JAVA:
// This seems to be essential to get good speeds, otherwise batching is not used.
conn.setAutoCommit(false);
PreparedStatement prepStmt = conn.prepareStatement("INSERT INTO TestTable (Col1, Col2) VALUES (?, ?)");
for (int i = 1; i <= 10000; i++) {
prepStmt.setString(1,"X");
prepStmt.setInt(2,100);
prepStmt.addBatch();
}
prepStmt.executeBatch();
conn.commit();
Run Code Online (Sandbox Code Playgroud)
BULK INSERT:
// A text file containing "X 100" over and over again... so the same data as generated in JAVA
bulk insert TestTable FROM 'c:\test\test.txt';
Run Code Online (Sandbox Code Playgroud)
尽管这BULK INSERT是进行批量插入的最快方法,但是SQL Server通过本机驱动程序和ODBC支持远程(客户端驱动)批量插入操作。从4.2版本起,JDBC驱动程序,这个功能是通过暴露的SQLServerBulkCopy类,它不直接从文件中读取,但确实从支持阅读RowSet,ResultSet或自定义实现ISQLServerBulkRecord对生成的数据。此功能等效于.NET SqlBulkCopy类,具有大致相同的接口,并且应该是执行基于服务器的批量操作的最快方法BULK INSERT。
编辑:OP的示例
在下面,您可以找到一个示例用例,该用例可用于测试SQLServerBulkCSVFileRecord的性能,该方法类似于SQLServerBulkCopy,但它从文本文件中读取内容。在我的测试案例中,test.txt包含一百万行,其中包含“ X tab
100”
CREATE TABLE TestTable (Col1 varchar(50), Col2 int);
Run Code Online (Sandbox Code Playgroud)
该表不应启用任何索引。
在JAVA中
// Make sure to use version 4.2, as SQLServerBulkCSVFileRecord is not included in version 4.1
import com.microsoft.sqlserver.jdbc.*;
long startTime = System.currentTimeMillis();
SQLServerBulkCSVFileRecord fileRecord = null;
fileRecord = new SQLServerBulkCSVFileRecord("C:\\temp\\test.txt", true);
fileRecord.addColumnMetadata(1, null, java.sql.Types.NVARCHAR, 50, 0);
fileRecord.addColumnMetadata(2, null, java.sql.Types.INTEGER, 0, 0);
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
Connection destinationConnection = DriverManager.getConnection("jdbc:sqlserver://Server\\\\Instance:1433", "user", "pass");
SQLServerBulkCopyOptions copyOptions = new SQLServerBulkCopyOptions();
// Depending on the size of the data being uploaded, and the amount of RAM, an optimum can be found here. Play around with this to improve performance.
copyOptions.setBatchSize(300000);
// This is crucial to get good performance
copyOptions.setTableLock(true);
SQLServerBulkCopy bulkCopy = new SQLServerBulkCopy(destinationConnection);
bulkCopy.setBulkCopyOptions(copyOptions);
bulkCopy.setDestinationTableName("TestTable");
bulkCopy.writeToServer(fileRecord);
long endTime = System.currentTimeMillis();
long totalTime = endTime - startTime;
System.out.println(totalTime + "ms");
Run Code Online (Sandbox Code Playgroud)
使用此示例,我能够达到每秒30000行的插入速度。
| 归档时间: |
|
| 查看次数: |
6000 次 |
| 最近记录: |