我有一个较大的(~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”列上进行一对一的匹配,而不是在其中进行文本搜索。
答案 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)。