【问题标题】:MySQL UPDATE Statement using LIKE with 2 Tables Takes DecadesMySQL UPDATE 语句使用 LIKE 和 2 个表需要几十年
【发布时间】:2013-11-09 00:36:21
【问题描述】:

您能告诉我为什么这样的查询需要这么长时间(字面意思是 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 行的较小测试查询速度。

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

DOM 加载时间从 44 秒缩短到 1 秒,增加了 98%。

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

【问题讨论】:

  • tempval_import_435 中没有 attr_id 列
  • 等等,这是一个错字。我修好了。
  • 你为什么用LIKE而不是=
  • @EdCottrell 查询在我认为应该使用的 varchar 列上LIKE
  • = 应该比LIKE 快得多——LIKE 仅用于匹配模式,如'%something%',它匹配文本中任何位置带有“something”的任何内容。跨度>

标签: mysql


【解决方案1】:

使用= 代替LIKE= 应该比 LIKE 快​​得多——LIKE 仅用于匹配模式,如 '%something%',它匹配文本中任何位置带有“something”的任何内容。

如果您有此查询:

SELECT * FROM myTable where myColumn LIKE 'blah'

MySQL 可以通过假装您输入myColumn = 'blah' 来优化这一点,因为它认为该模式是固定的并且没有通配符。但是,如果您的 upc 列中有这些数据怎么办:

blah
foo
bar
%foo%
%bar
etc.

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

【讨论】:

  • 感谢您提供有趣的信息。我认为查询优化器可以快速执行SELECT COUNT(*) FROM table WHERE myColumn LIKE '\%'(或类似_)来确定它是否可以使用= 符号优化最终查询。但我想它不会。我很快就会试一试。
  • 我在一个大约 1000 行的较小数据集上对其进行了测试。 = 大约需要 1 秒,而 LIKE 大约需要 44 秒。谢谢!
【解决方案2】:

本质上,您加入了一个 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`

【讨论】:

  • 您好,感谢您的建议。我的 MySQL 版本除了 SELECT 语句外不支持 EXPLAIN,但我可能很快会升级。不过,我确实感觉到正在处理某种笛卡尔结果。更新 30k 条记录应该不需要 17 分钟。
  • 我认为 MySQL 可能会使用我的语法在内部执行与您在您的语法中明确使用的相同类型的连接。无论哪种方式,LIKE 字段比较查询大约需要 44 秒,= 大约需要 1 秒。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-01-22
  • 1970-01-01
  • 1970-01-01
  • 2012-10-17
  • 1970-01-01
  • 2016-02-24
  • 1970-01-01
相关资源
最近更新 更多