如何加快对mysql数据库中的大表(200k +行)进行更改?

时间:2011-10-18 01:29:51

标签: mysql

我的mysql数据库里面有一个表,我经常需要更改并插入行,但是当我进行更改时它会继续运行很慢,因为有超过200k +的条目。我测试了另一个表,它只有很少的行并且移动很快,所以它不是服务器或数据库本身,而是那个特别困难的表。我需要所有表的行,但无法找到解决负载问题的解决方案。

DROP TABLE IF EXISTS `articles`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `articles` (
  `id` int(11) NOT NULL auto_increment,
  `content` text NOT NULL,
  `author` varchar(255) NOT NULL,
  `alias` varchar(255) NOT NULL,
  `topic` varchar(255) NOT NULL,
  `subtopics` varchar(255) NOT NULL,
  `keywords` text NOT NULL,
  `submitdate` timestamp NOT NULL default CURRENT_TIMESTAMP,
  `date` varchar(255) NOT NULL,
  `day` varchar(255) NOT NULL,
  `month` varchar(255) NOT NULL,
  `year` varchar(255) NOT NULL,
  `time` varchar(255) NOT NULL,
  `ampm` varchar(255) NOT NULL,
  `ip` varchar(255) NOT NULL,
  `score_up` int(11) NOT NULL default '0',
  `score_down` int(11) NOT NULL default '0',
  `total_score` int(11) NOT NULL default '0',
  `approved` varchar(255) NOT NULL,
  `visible` varchar(255) NOT NULL,
  `searchable` varchar(255) NOT NULL,
  `addedby` varchar(255) NOT NULL,
  `keyword_added` varchar(255) NOT NULL,
  `topic_added` varchar(255) NOT NULL,
  PRIMARY KEY  (`id`),
  KEY `score_up` (`score_up`),
  KEY `score_down` (`score_down`),
  FULLTEXT KEY `SEARCH` (`content `),
  FULLTEXT KEY `asearch` (`author`),
  FULLTEXT KEY `topic` (`topic`),
  FULLTEXT KEY `keywords` (`content `,`keywords`,`topic`,`author`),
  FULLTEXT KEY `content ` (`content `,`keywords`),
  FULLTEXT KEY `new` (`keywords`),
  FULLTEXT KEY `author` (`author`)
) ENGINE=MyISAM AUTO_INCREMENT=290823 DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;

6 个答案:

答案 0 :(得分:6)

依赖索引:

更多索引 =选择速度更快,插入速度更慢

减少索引 =选择速度慢,插入速度更快

因为插入时必须重建索引表,并且表中的数据越多,mysql重建索引的工作就越多。

所以也许您可以删除不需要的索引,这样可以加快插入速度。

答案 1 :(得分:2)

另一种选择是将你的桌子分成许多 - 这会阻止瓶颈。

答案 2 :(得分:1)

尝试在更新脚本中传递更改。这很慢,因为它创建表。尝试更新已进行更改的表格。

例如,创建一个捕获程序中所有更改的变量,然后将其插入到表查询中。对于程序而言应该足够快。但众所周知,速度取决于处理的数据量。

如果您还有其他需要,请告诉我。

答案 3 :(得分:1)

这可能会或可能不会直接帮助您,但我注意到您的表中有很多VARCHAR(255)列。其中一些似乎完全没必要 - 你真的需要所有date / day / month / year / time / {{1 }} 列? - 许多可以被更紧凑的数据类型取代:

  • 日期可以存储为ampm(或DATETIME)。
  • IP地址可以存储为TIMESTAMP,也可以存储为INTEGER
  • 您应该创建一个单独的用户表,并使用BINARY(16)键引用它,而不是在文章表中存储用户名。
  • 我不知道INTEGERapprovedvisible字段是什么,但我打赌它们不一定是searchable

我还要第二次Adrian Cornish's suggestion来分割你的桌子。特别是,您确实希望保持频繁更改和频繁访问的元数据,例如上/下投票得分,与很少更改和不经常访问的批量数据(如文章内容)分开。请参阅示例http://20bits.com/articles/10-tips-for-optimizing-mysql-queries-that-dont-suck/

答案 4 :(得分:0)

“我的mysql数据库里面有一个表,我经常需要改变并插入行但是它会继续”

如果您的应用程序执行A LOT更新,请在此表上尝试innodb,并在那里同时插入,行级别锁定$$$

答案 5 :(得分:0)

我建议你在几个表中拆分那个“大表”(实际上并不是那么大,但对于MySQL来说),以充分利用查询缓存。每次更新该表中的某些记录时,都会删除查询缓存。您也可以尝试降低隔离级别,但这有点复杂。