我有一个大数据数组,我尝试插入到我的数据库中,然后删除旧表并重命名新表。为了更快地做到这一点,我使用TRANSACTION(它不会影响我的问题,我试过没有它)并在async.each函数中进行每个MySQL查询。在这个async.each的回调中,我执行COMMIT(用于事务),删除和重命名。
通常我要插入100000或更多行。如果我在终端中使用“SELECT COUNT(*)”,我可以看到这些行插入的速度很慢,但不知何故,当插入1/4行时,该过程立即结束。然后我在一瞬间得到了一张满桌子。我不知道为什么会这样,我很好,但也许这就是我问题的原因。
所以这是我的问题:我在插入时无法从Node访问数据库。但我仍然可以从终端访问它,我可以计算行,查看表等。如果Node调用其他函数与mysql查询,此查询将等待,直到该大插入将结束。 这就像Node代码并行工作,但mysql查询只在一个线程中工作。我该如何解决这个问题?
exports.insertSubscribers = function(data, db_name, done){
state.pool.query('START TRANSACTION');
async.each(data, function(row, cb){
state.pool.query('INSERT INTO new_' + db_name + ' (id, first_name, last_name, sex, city, country, photo_200) VALUES (' + "'" + row.id + "', " + "'" + row.first_name + "', " + "'" + row.last_name + "', " + "'" + row.sex + "', " + "'" + JSON.stringify(row.city) + "', " + "'" + JSON.stringify(row.country) + "', " + "'" + row.photo_200 + "'" + ')', cb);
}, end_transaction);
function end_transaction(){
state.pool.query('COMMIT', function(err){
if(err) return done(err);
state.pool.query('SHOW TABLES LIKE \'' + db_name + '\'', function(err, result){
if(result.length != 0){
state.pool.query('DROP TABLE ' + db_name, function(err){
if(err) return done(err);
state.pool.query('RENAME TABLE new_' + db_name + ' TO ' + db_name, function(err){
if(err) return done(err);
});
});
}else{
state.pool.query('RENAME TABLE new_' + db_name + ' TO ' + db_name, function(err){
if(err) return done(err);
});
}
});
});
}
};
答案 0 :(得分:0)
MySQL设计只允许在任何给定时间每个连接最多一个查询。所以一些MySQL驱动程序/模块所做的就是简单地维护一个内存中的队列,当另一个正在进行其他查询时使用该队列。
一种可能的解决方法是在池中使用多个连接(例如mysql
和mysql2
模块具有内置池支持),以便您可以并行执行更多查询。 / p>