Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MySql批量插入-Windows 10任务管理器上的磁盘使用率为100%_Mysql_Performance - Fatal编程技术网

MySql批量插入-Windows 10任务管理器上的磁盘使用率为100%

MySql批量插入-Windows 10任务管理器上的磁盘使用率为100%,mysql,performance,Mysql,Performance,我正在尝试使用MySQL批处理准备语句插入多行 我正在本地机器上测试:Windows10,MySQL服务器8.0和EclipsePhoton 当代码开始批处理时,我的笔记本电脑性能会降低。通过查看TaskManager,我发现磁盘使用率达到了100% 如果我停止在Eclipse上运行,磁盘使用就会正常化,性能问题也就消失了。我总是试图运行我的代码 我不确定问题是我的代码还是我的笔记本电脑,因为我在用mysql启动windows时遇到了同样的问题。我需要等待几分钟,直到我的磁盘使用变得正常,我开始

我正在尝试使用MySQL批处理准备语句插入多行

我正在本地机器上测试:Windows10,MySQL服务器8.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) {

    }
}

已解决:我在
my.cnf
更改为中解决了这个问题

innodb_buffer_pool_size = 4G
对于您的8GB机器。然后重新启动mysql

由于RAM中缺少缓存,当前的微小8M设置会导致大量I/O

(如果4G对于其他运行的设备来说太大了,选择其他的数字,但至少尝试300M。)

我很惊讶Win 10只跑了8克

令我惊讶的是,8.0版一开始只有一个很小的8M。您是否继承了很久以前的设置(当8M是默认设置时)?我认为5.5版在2010年将默认值提高到了1.28亿

更多分析:

ip
上的索引可能占40MB左右。我想,IP地址是随机输入的吧?每次插入新行时,
ip
的索引都会更新。也就是说,一个40MB的块(16KB大小)被提取、修改并存储回磁盘。假设随机访问和40MB:8MB,则此获取修改写入需要命中磁盘的时间占80%。也就是说,对于每1000行的集群,仅对于
ip
索引,就有800*2个磁盘命中。此外,“顺序”写入的数据和其他索引也会有一定数量(较小数量)的点击。我猜大概还有20*1次磁盘点击


这只是一个粗略的计算。但它指出,如果您的缓冲池超过40MB(假设至少100MB,考虑到我没有提到的各种因素),那么几乎所有I/O都将消失。所有内容都将被缓存,因此不需要“获取”。“写入”可以延迟,不必重新执行。

您能给我们看一个已完成的样本吗
插入
?和
显示创建表
。索引是解决问题的重要部分。多少公羊?innodb\u buffer\u pool\u size的值是多少?@RickJames,我编辑了我的文章,包括更多信息。我不理解您的问题“示例已完成插入”。您提供的代码是Java?/Eclipse?我想看看它生成的SQL。@RickJames,是的,它是Java。我正在使用Eclipse。我使用的SQL命令仅在上面的代码段中可以看到:String SQL=“INSERT INTO log(date、ip、request、status、userAgent)value(?,,,,,,?)”;嗯,我怀疑
addBatch
会导致一个“批处理”插入,其中它构建一个包含1K行的长
insert
字符串,然后执行它。如果它不是批处理的,那么我的回答中的分析需要一些更改。我将innodb_buffer_pool_size更新为4G,但它无法解决问题。我重新启动了mysql和Windows。之后,我尝试在插入记录之前删除索引(之后我将重新创建),但也不起作用。我将尝试在Linux上进行测试。如果“批处理”实际上是一次一个,请尝试在\u trx\u commit=2处使用innodb\u flush\u log\u并重新启动。
innodb_buffer_pool_size = 4G