我正在尝试使用mysql批处理准备语句插入多行。
我正在本地机器上进行测试:Windows10和MySQLServer8.0以及EclipsePhoton。
当代码开始批处理时,我的笔记本电脑性能会减慢。看看taskmanager,我发现磁盘使用率达到了100%。
如果我停止在eclipse上运行,磁盘使用就会正常化,性能问题也就消失了。我总是试图运行我的代码。
我不确定是我的代码出了问题还是我的笔记本电脑出了问题,因为我在打开笔记本电脑时遇到了同样的问题,用mysql启动windows。我需要等待几分钟,直到我的磁盘使用变得正常,我开始使用我的笔记本电脑。
private static final String CONNECTION_STRING = "jdbc:mysql://localhost/parser?user=root&password=root&useTimezone=true&serverTimezone=UTC";
MySQLAccess(boolean debug) throws ClassNotFoundException, SQLException{
Class.forName("com.mysql.cj.jdbc.Driver");
connect = DriverManager
.getConnection(CONNECTION_STRING);
isDebug = debug;
}
private void insertLogTable(List<Map<String, Object>> logList) throws SQLException{
String sql = "INSERT INTO log (date, ip, request, status, userAgent) VALUES (?, ?, ?, ?, ?)";
PreparedStatement ps = connect.prepareStatement(sql);
int i = 0;
for (Map<String, Object> log : logList) {
ps.setString(1, getMySQLDateString((Date)log.get("date")));
ps.setString(2, (String)log.get("ip"));
ps.setString(3, (String)log.get("request"));
ps.setString(4, (String)log.get("status"));
ps.setString(5, (String)log.get("userAgent"));
ps.addBatch();
i++;
if (i % 1000 == 0 || i == logList.size()) {
ps.executeBatch(); // Execute every 1000 items.
debug(getMySQLDateString((Date)log.get("date")));
}
}
ps.close();
}
public void close() {
try {
if (connect != null) {
connect.close();
}
} catch (Exception e) {
}
}
编辑:
我运行了“select@@innodb\u buffer\u pool\u size”,得到了“8388608”。
我的笔记本电脑有8gb的内存。
CREATE TABLE `log` (
`date` datetime NOT NULL,
`ip` varchar(15) NOT NULL,
`request` varchar(20) NOT NULL,
`status` varchar(3) NOT NULL,
`userAgent` varchar(256) NOT NULL,
`id` int(11) NOT NULL AUTO_INCREMENT,
`logcol` varchar(45) DEFAULT NULL,
`logcol1` varchar(45) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `ip_index` (`ip`),
KEY `date_index` (`date`)
) ENGINE=InnoDB AUTO_INCREMENT=915169 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
已解决:我解决了以下问题:如何使用executebatch提高性能?
1条答案
按热度按时间b5buobof1#
在
my.cnf
更改为对于8gb的机器。然后重启mysql。
由于ram中缺少缓存,当前的微小8m设置会导致显著的i/o。
(如果4g对于其他运行的东西来说太大了,可以选择其他的数字,但至少要尝试300m。)
我很惊讶赢10只会跑8克。
我很惊讶8.0版一开始只有一个很小的8m。您是否继承了很久以前的设置(默认值为8m)?我认为5.5版本在2010年将默认值提高到了1.28亿!
更多分析:
上的索引
ip
可能占用40mb左右。我想,ip地址是随机的?每次插入新行时ip
已更新。也就是说,40mb中的一个块(16kb大小)被提取、修改并存储回磁盘。假设随机访问和40mb:8mb,那么80%的时间需要访问磁盘。也就是说,对于1000行的每一个块,就有8002个磁盘命中ip
索引。此外,对于“顺序”写入的数据和其他索引,也会有一些命中次数(较小的次数)。我猜大概还有201次磁盘点击。那只是一个粗略的计算。但它指出,如果缓冲池大于40mb(假设至少100mb,考虑到我没有提到的各种因素),那么几乎所有的i/o都将消失。所有内容都将被缓存,因此不需要“获取”。而“写入”可以延迟,不必重新进行。