Мне нужно обновить 2M * 2rows в базе данных mysql.
Вся информация находится в файле, который я обрабатываю с помощью php.Я получаю информацию в массиве, а затем помещаю ее в базу данных, используя
UPDATE processed
SET number1=$row[1], number2=$row[2], timestamp=unix_timestamp()
where match (id) against ('\"$id\"' IN BOOLEAN MODE) limit 1
Это работает - но это занимает слишком много времени ...
У меня есть индекс (основной) на(id).
Я пытался использовать что-то еще, кроме (id), которое включено в полнотекстовый индекс (я использую Myisam) - это даже медленнее.
Поскольку моя база данных довольно большаяи mysql должен пройти через все, чтобы найти нужную строку для обновления, это занимает несколько секунд на обновление ... что означает несколько дней для обработки моего обновления!
Есть ли более быстрый способ сделать это?Если я переключусь на innodb, это будет быстрее?(Даже если это не так, я думаю, что это может быть круто во время обновления, вся моя таблица не будет заблокирована).
Поскольку числа 1 и 2 являются числами, я собираюсь сгруппировать все (идентификаторы), которые имеютбыть обновленным до того же номера - это будет быстрее?
Есть ли способ настроить mysqld так, чтобы столбцы number1, number2 и id оставались в оперативной памяти, делая его более быстрым для доступа / обновления?
Любая идея приветствуется, так как я полностью потерян ...:)
edit: добавление примера кода, чтобы вы могли понять мою ситуацию:
foreach ($data_rows as $rows) {
$row=explode(":", $rows); // $row[0] info
// $row[1] new number1
// $row[2] new number2
$query = $db->query("select * from processed where match (info) against ('\"$info\"' IN BOOLEAN MODE) limit 1");
while ($line = $query->fetch_object())
{
$data[$line->hash]['number1']=$line->number1;
$data[$line->hash]['number2']=$line->number2;
$id=$line->id;
}
if (is_array($data[$info])) { // Check if we have this one in the database.
// If the number is correct, no need to update.
if (($data[$info]['number1'] != $row[1]) && ($data[$info]['number2'] != $row[2])) {
$db->query("UPDATE processed SET number1=$row[1], number2=$row[2], timestamp=unix_timestamp() where id=$id");
print "updated - $info - $row[1] - $row[2]\n";
}
}
else {
print "$info not in database\n";
}
}
shema:
CREATE TABLE `processed` (
`id` int(30) NOT NULL AUTO_INCREMENT,
`timestamp` int(14) DEFAULT NULL,
`name` text,
`category` int(2) DEFAULT '0',
`subcat` int(2) DEFAULT '0',
`number1` int(20) NOT NULL,
`number2` int(20) NOT NULL,
`comment` text,
`hash` text,
`url` text,
PRIMARY KEY (`id`),
FULLTEXT KEY `name` (`name`),
FULLTEXT KEY `hash` (`hash`)
) ENGINE=MyISAM AUTO_INCREMENT=1328365 DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
отредактируйте снова:
ANALYZE TABLE processed;
очень помогли улучшить время моего UPDATEs
.(свежие индексы!)
Добавит мои данные в другую таблицу и все равно присоединится к обновлению:)