我最近将项目表切换到了InnoDB(认为关系将是一件好事)。我使用PHP脚本一次为大约500个产品编制索引。InnoDB插入速度很慢,速度很慢
表中存储字/ ID相关联:
CREATE TABLE `windex` (
`word` varchar(64) NOT NULL,
`wid` int(10) unsigned NOT NULL AUTO_INCREMENT,
`count` int(11) unsigned NOT NULL DEFAULT '1',
PRIMARY KEY (`wid`),
UNIQUE KEY `word` (`word`)
) ENGINE=InnoDB AUTO_INCREMENT=324551 DEFAULT CHARSET=latin1
另一个表存储产品ID /字ID关联:
CREATE TABLE `indx_0` (
`wid` int(7) unsigned NOT NULL,
`pid` int(7) unsigned NOT NULL,
UNIQUE KEY `wid` (`wid`,`pid`),
KEY `pid` (`pid`),
CONSTRAINT `indx_0_ibfk_1` FOREIGN KEY (`wid`) REFERENCES `windex` (`wid`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `indx_0_ibfk_2` FOREIGN KEY (`pid`) REFERENCES `product` (`ID`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1
脚本使用MyISAM的测试,它索引的产品比较快的(多,比InnoDB快得多)。第一次运行在InnoDB上的时候速度很慢,但是在嵌套更多的值之后,我最终加速了很多(但还不够)。
我会假设innodb会因为rowlevel锁而对这种类型的事物快得多,但事实并非如此。
我建立一个查询,看起来像:
SELECT
title,keywords,upc,...
FROM product
WHERE indexed = 0
LIMIT 500
我创建了一个循环,并与所有需要被添加到WINDEX和所有需要的单词ID /产品ID对的话填充数组被添加到indx_0。
因为每当我做一个“REPLACE INTO”或“INSERT IGNORE INTO”由于重复值而失败时innodb会不断增加我的自动增量值,所以我需要确保我添加的值不存在。要做到这一点我首先选择存在使用查询像这样的价值观:
SELECT wid,word
FROM windex
WHERE
word = "someword1" or word = "someword2" or word = "someword3" ... ...
然后我过滤掉我的阵列针对其存在,因此所有的生字我加100%的新成果。
这占用了整个执行时间的大约20%。其他80%将这些配对值添加到indx_0中,其中有更多的值。
下面是我得到的一个例子。
0.4806秒选择产品。 (总共0.4807秒)。
0.0319秒收集500个项目。 (总共0.5126秒)。
5.2396秒选择windex值进行比较。 (共5.7836秒)。
1.8986秒更新计数。 (总共7.6822秒)。
0.0641秒添加832个windex记录。 (总共7.7464秒)。
17.2725秒添加3435个pid/wid对的索引。 (总共25.7752秒)。
操作耗时26.07秒,对500种产品进行索引。
的3435对正在在一个单一的查询执行,如:
INSERT INTO indx_0(pid,wid)
VALUES (1,4),(3,9),(9,2)... ... ...
为什么是这么的InnoDB远远低于在我的案件的MyISAM?
创建某种搜索功能的单词索引的想法是什么?如果是这样的话,那么一直在那里做,检查一个真正的搜索引擎,例如solr或mysql全文搜索。无法超越这些特定的任务。 – 2012-02-02 15:54:31