mySQL大文本比较性能......最佳实践?

时间:2009-02-04 14:23:17

标签: mysql performance indexing

我有一个较大的(~1.5M记录)表,其中包含不同长度的文本字符串,我在其中运行查询以查找匹配项:

CREATE TABLE IF NOT EXISTS `shingles` (
  `id` bigint(20) NOT NULL auto_increment,
  `TS` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
  `shingle` varchar(255) NOT NULL,
  `count` int(11) NOT NULL default '0',
  PRIMARY KEY  (`id`),
  KEY `shingle` (`shingle`,`TS`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=1571668;

我的问题是我需要在对这个表进行比较时不断添加和删除数据,因此维护索引很难。

我正在寻找及时管理插入的最佳实践,同时最大化选择的吞吐量。这个过程每天24小时运行,需要尽可能快。

感谢任何帮助。

更新: 为了澄清,我正在“shingle”列上进行一对一的匹配,而不是在其中进行文本搜索。

2 个答案:

答案 0 :(得分:1)

首先:你的bigint主键可能会在这里杀死你,这是一个非常昂贵的类型,试图维护。 150万条记录远未达到无符号整数(约42亿)的限制。

在InnoDB中使用big int作为主键更糟糕,因为它将PK存储在每个其他索引中的每个条目中,因此可以部分解释您尝试切换时出现的问题。一旦你在表格中添加和删除,如果有很多并发交易,MyISAM就会被搞砸。

绕过字符串比较费用的一个技巧是存储crc32(shingle)以及shingle。然后,您可以索引此列,但不是您的varchar。以下是我如何做的事情:

CREATE TABLE IF NOT EXISTS `shingles` (
  `id` int unsigned NOT NULL auto_increment,
  `TS` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
  `crc` int unsigned not null,
  `shingle` varchar(255) NOT NULL,
  `count` int(11) NOT NULL default '0',
  PRIMARY KEY  (`id`),
  KEY `crc` (`crc`)
)
insert into shingles (crc, shingle, count) values (crc32('testtest'),'testtest',1),(crc32('foobar'),'foobar',4);
select * from shingles where crc = crc32('foobar') and shingle = 'foobar';

如果您打算查询'ts',请将其添加为crc索引的第二个组件

答案 1 :(得分:0)

对于初学者,使用InnoDB而不是MyISAM。这也解决了在进行插入时进行查询的问题。

您可能需要稍微调整一下mysql配置,以便将内存用于innodb(innodb_buffer_pool_size而不是key_buffer_size)。