使用LIKE和2个表的MySQL UPDATE语句需要几十年

时间:2013-11-09 00:36:21

标签: mysql

你能告诉我为什么这样的查询需要这么长时间(字面上20-30分钟)吗? 我似乎设置了适当的索引,不是吗?

UPDATE  `temp_val_import_435` t1,
`attr_upc` t2 SET t1.`attr_id` = t2.`id` WHERE t1.`value` LIKE t2.`upc`


CREATE TABLE `attr_upc` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `upc` varchar(255) NOT NULL,
 `last_update` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
 PRIMARY KEY (`id`),
 UNIQUE KEY `upc` (`upc`),
 KEY `last_update` (`last_update`)
) ENGINE=InnoDB AUTO_INCREMENT=102739 DEFAULT CHARSET=utf8


CREATE TABLE `temp_val_import_435` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `attr_id` int(11) DEFAULT NULL,
 `translation_id` int(11) DEFAULT NULL,
 `source_value` varchar(255) NOT NULL,
 `value` varchar(255) DEFAULT NULL,
 `count` int(11) NOT NULL,
 PRIMARY KEY (`id`),
 KEY `core_value_id` (`core_value_id`),
 KEY `translation_id` (`translation_id`),
 KEY `source_value` (`source_value`),
 KEY `value` (`value`),
 KEY `count` (`count`)
) ENGINE=InnoDB AUTO_INCREMENT=32768 DEFAULT CHARSET=utf8
Ed Cottrell的解决方案为我工作。使用=代替LIKE可以在1000行上加快一个较小的测试查询。

我测量了两种方式:1在phpMyAdmin中,另一种在查看DOM加载的时间(当然这涉及其他过程)。

DOM负载从44秒增加到1秒,增加了98%。

但查询执行时间的差异更为显着,从43.4秒变为0.0052秒,减少了99.988%。非常好。我将报告大数据集的结果。

2 个答案:

答案 0 :(得分:2)

使用=代替LIKE=应该比LIKE快得多 - LIKE仅用于匹配模式,例如在'%something%'中,它匹配文本中任何地方的“某事”。

如果您有此查询:

SELECT * FROM myTable where myColumn LIKE 'blah'

MySQL可以通过伪装你输入myColumn = 'blah'来优化它,因为它看到模式是固定的并且没有通配符。但是,如果您在upc列中包含此数据,该怎么办:

blah
foo
bar
%foo%
%bar
etc.

MySQL无法提前优化您的查询,因为它尝试与匹配的文本可能是模式,例如%foo%。因此,它必须针对LIKE的每个值对temp_val_import_435.value的每个值执行attr_upc.upc次匹配的全文搜索。使用简单的=和您定义的索引,这是不必要的,查询应该快得多。

答案 1 :(得分:0)

从本质上讲,你正在加入一个有问题的LIKE(如果使用索引则需要EXPLAIN才能看到MySQL)。试试这个:

UPDATE  `temp_val_import_435` t1
INNER JOIN `attr_upc` t2
  ON t1.`value` LIKE t2.`upc`
SET t1.`attr_id` = t2.`id` WHERE t1.`value` LIKE t2.`upc`