将数据插入Mysql越来越慢

时间:2016-09-24 08:24:04

标签: c# mysql database mariadb

我需要每分钟向本地数据库插入388个数据。 当表为空时,我只需要5秒钟即可插入数据库。

但是当表格变大时,当行数达到1,026,558时,程序效能会减慢到一分钟以上。

CPU的使用率为100%。这很不寻常。

这是我的代码:

public static void dataToDB(String[] routeIDArray,String[] levelArray,String[] valueArray,String[] travelTimeArray, int amountOfData)
    {
        MySqlConnection con = new MySqlConnection(connStr);
        MySqlCommand cmd = null;
        MySqlDataReader rdr = null;
        String sqlCmd, updateSqlCmd = "UPDATE `datetimetable` SET ";
        for(int counter = 0; counter < amountOfData; counter++)
        {
            sqlCmd = "ALTER TABLE `datetimetable` ADD COLUMN IF NOT EXISTS `" + routeIDArray[counter] + "` INT NULL;"
                + "INSERT INTO `roadvalue`.`data` (`level`,`value`,`traveltime`) VALUES ("
                + levelArray[counter] + ","
                + valueArray[counter] + ","
                + travelTimeArray[counter] + ");"
                + "SELECT LAST_INSERT_ID() FROM `data`;";
            cmd = new MySqlCommand(sqlCmd, con);
            con.Open();
            rdr = cmd.ExecuteReader();
            rdr.Read();
            updateSqlCmd += "`" + routeIDArray[counter] + "` = " + rdr[0] + ",";
            rdr.Close();
        }
        updateSqlCmd = updateSqlCmd.TrimEnd(',');
        updateSqlCmd += " WHERE EXISTS (SELECT * WHERE dateTime = '" + dateTime.ToString("yyyy-MM-dd HH:mm:00") + "');";
        cmd = new MySqlCommand(updateSqlCmd, con);//update data key to datetimetable
        cmd.ExecuteNonQuery();
        Console.WriteLine("Done.");
        con.Close();
    }
    public static void checkDateTimeExisted()
    {
        MySqlConnection con = new MySqlConnection(connStr);
        MySqlCommand cmd;
        String sqlCmd;
        sqlCmd = "INSERT INTO `datetimetable` (`dateTime`) SELECT * FROM (SELECT '" + dateTime.ToString("yyyy-MM-dd HH:mm:00")
                     + "') AS tmp WHERE NOT EXISTS(SELECT `dateTime` FROM `datetimetable` WHERE `dateTime` = '" + dateTime.ToString("yyyy-MM-dd HH:mm:00") + "') LIMIT 1; ";

            con.Open();
            cmd = new MySqlCommand(sqlCmd, con);
            cmd.ExecuteNonQuery();
            con.Close();
    }

并且Mysql Engine是InooDB,表“data”有一个Auto_Increment主键,表“datetimetable”有一个Auto_Increment主键和一个不重复的日期时间作为索引。

我做错了什么?

2 个答案:

答案 0 :(得分:0)

我找到答案,命令“SELECT LAST_INSERT_ID()FROM data;”应该添加LIMIT 1,否则它将使所有ID杀死性能。

答案 1 :(得分:0)

不要在循环中使用ALTER TABLE - 提前计划并在开始之前提供所有列。

不要在单个字符串中使用多个语句。这具有安全隐患等。

当(我认为)简单的WHERE EXISTS...可行时,请勿使用WHERE

如果有UNIQUE(datetime),则最终的INSERT可以是

INSERT IGNORE INTO datetimetable
    (datetime)
    VALUE
    ('...');

除非您需要LAST_INSERT_ID(),否则请进行批量插入。 <{1}}不应该是必要的。

不要'标准化'日期时间值;它只能减慢速度。只需将日期时间放在主表中即可。