美好的一天,我之前发布过这个问题,但似乎我还不够清楚,所以我会尽量详细说明我的情况。
我需要实现一个解决方案,每天从一些 CSV 文件中提取数据,并仅使用 JDBC 将这些数据插入到生产环境数据库表中。
我必须插入 2 个表
表格:
Table1 (
[func] [varchar](8) NOT NULL,[Ver] [smallint] NOT NULL,[id] [varchar](32) NOT NULL,[desc] [varchar](300) NOT NULL,[value] [float] NOT NULL,[dtcreated] [date] NOT NULL,[dtloaded] [date] NULL,CONSTRAINT [Table1_PK] PRIMARY KEY CLUSTERED
(
[func] ASC,[ver] ASC,[id] ASC,[desc] ASC,[dtcreated] ASC
);
table2 (
[id] [varchar](32) NOT NULL,[f1] [varchar](50) NOT NULL,[f2] [varchar](32) NOT NULL,[f3] [varchar](6) NULL,[f4] [varchar](3) NULL,[f5] [varchar](3) NULL,[f6] [varchar](32) NULL,[DtStart] [date] NOT NULL,[DtEnd] [date] NOT NULL,CONSTRAINT [table2_PK] PRIMARY KEY CLUSTERED
(
[id] ASC,[DtStart] DESC,[DtEnd] DESC
)
Table1 的大小为 400+GB,有 6,500+ 百万条记录。 表 2 的大小为 30+GB,大约有 500 万条记录。
在 table1 中,我需要处理和插入 150 万条记录。
在 table2 中,我需要处理和更新/插入 110 万条记录,这是使用匹配时合并查询完成的。
我需要能够在不中断这些表的使用的情况下执行这两个过程。
我的代码执行以下操作
public void processFile(String fileLocation) throws IOException,SQLException{
try {
SqlClient sqlClient = SqlClient.from(DriverClassname.SQLSERVER,DriverConnectionString.barra());
Connection connection = sqlClient.getconnection();
PreparedStatement pstmt = connection.prepareStatement(getSql());
File file = new File(fileLocation);
try (BufferedReader br = new BufferedReader(new FileReader(file))) {
int lnproc = 0;
int batchCount = 0;
String line;
while (((line = br.readLine()) != null) {
String[] parts = line.split(",");
pstmt.clearParameters();
.....//Process parts and add them to the preparestatement
pstmt.addBatch();
batchCount++;
if(batchCount>=batchSize){
batchCount = 0;
try {
pstmt.executeBatch();
}catch (BatchUpdateException ex){
}
}
}
try {
pstmt.executeBatch();
}catch (BatchUpdateException ex){
}
}
connection.commit();
connection.close();
} catch (ClassnotFoundException | InstantiationException | IllegalaccessException e) {
}
}
由于要在每个表中插入大量记录,我可以在可能影响生产环境的表上生成不同的锁。
我做了一些研究,我正在考虑使用多种策略
- 创建最多 5k 个插入的批次并提交它们以防止锁升级
- 在每条记录之后提交以防止锁定和 交易日志。
我想就您认为在这种情况下使用的最佳策略征求社区的意见。
以及你可以给我的任何建议。