我最近将我的项目表切换到InnoDB(认为关系将是一件好事)。我正在使用PHP脚本一次索引大约500个产品。
存储word / ids关联的表:
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对于这种类型的东西来说要快得多,因为行级锁定但事实并非如此。
我构建了一个类似于:
的查询SELECT
title,keywords,upc,...
FROM product
WHERE indexed = 0
LIMIT 500
我创建一个循环并填充一个数组,其中包含需要添加到windex的所有单词以及需要添加到indx_0的所有单词id / product id对。
因为innodb不断增加我的自动增量值,每当我执行“REPLACE INTO”或“INSERT IGNORE INTO”因重复值而失败时,我需要确保我添加的值不存在。为此,我首先使用如下查询选择所有存在的值:
SELECT wid,word
FROM windex
WHERE
word = "someword1" or word = "someword2" or word = "someword3" ... ...
然后我根据存在的结果筛选出我的数组,这样我添加的所有新单词都是100%新的。
这占总执行时间的20%左右。另外80%用于将对值添加到indx_0中,其中有更多值。
以下是我得到的一个例子。
0.4806秒选择产品。 (总共0.4807秒) 收集500件物品0.0319秒。 (总共0.5126秒) 5.2396秒选择windex值进行比较。 (总共5.7836秒) 1.8986秒更新计数。 (总计7.6822秒) 添加832个windex记录0.0641秒。 (总共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慢得多?
答案 0 :(得分:18)
InnoDB提供比MyIsam(FOREIGN KEYS
)更复杂的密钥结构,并且InnoDB中的重新生成密钥非常慢。你应该把所有更新/插入语句都包含在一个事务中(这些事实在InnoDB中实际上非常快,一旦我在带有2个索引的InnoDb表上有大约300 000个插入查询,它花费了大约30分钟,一旦我将每10 000个插入包含在{ {1}}和BEGIN TRANSACTION
花了不到2分钟。)
我建议使用:
COMMIT
这将导致InnoDB刷新索引一次不是几百次。
让我知道它是否有效
答案 1 :(得分:6)
我遇到了类似的问题,似乎InnoDB默认启用innodb_flush_log_at_trx_commit,它会刷新hdd日志文件中的每个插入/更新查询。硬盘的写入速度是这个过程的瓶颈。
所以尝试修改你的mysql配置文件
`innodb_flush_log_at_trx_commit = 0`
重启mysql服务。
我在插入时遇到了x100加速。