mysql更新是如此之慢 - 是否有更快的方式来更新数据?

时间:2011-09-13 16:22:03

标签: mysql sql full-text-search

我必须在mysql数据库中更新2M * 2rows。

所有信息都在一个文件中,我用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& number2是数字,我虽然将所有必须更新的(id)分组到相同的数字 - 会更快吗?

有没有办法调整mysqld以便number1,number2& id colums会留在RAM中,使访问/更新更快吗?

任何想法都是受欢迎的,因为我完全迷失了...... :)

编辑:添加示例代码,以便您了解我的情况:

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";
    }
                }   

玛:

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的时间方面做了很多帮助。 (新指数!)

将我的数据添加到另一个表格中无论如何加入更新:)

3 个答案:

答案 0 :(得分:1)

您正在执行2M * 2 UPDATE个命令。这需要一段时间......

我建议您将文件内容转储到临时表中,然后运行单个UPDATE命令。

<强>更新

以下是您如何运行单个加入UPDATE

UPDATE processed 
inner join DumpTable on processed.id = DumpTable.id
SET number1=DumpTable.value1 , number2=DumpTable.value2, timestamp=unix_timestamp()

答案 1 :(得分:0)

那么a)你应该始终清理你的数据 -

sprintf("UPDATE processed 
         SET number1=%d, number2=%d, timestamp=unix_timestamp() 
         WHERE match (id) 
         AGAINST ('%d' $id IN BOOLEAN MODE) limit 1",
         mysql_real_escape_string($row[1]),
         mysql_real_escape_string($row[2]),
         mysql_real_escape_string($id)
);

此外,如果你切换到InnoDB它可能会稍微快一点,但是,对于很多人来说这是一个更好的选择,因为你没有锁定你正在为每个UPDATE工作的整个表,你只能锁定行你正在更新。

因此,最需要考虑的是,请阅读以下链接:http://www.kavoir.com/2009/09/mysql-engines-innodb-vs-myisam-a-comparison-of-pros-and-cons.html

答案 2 :(得分:0)