mysql - 大 MySQL 表,REPLACE -> 非常慢的查询

标签 mysql myisam

我在 MyISAM 数据库中有一个包含 1760 万行的表。

我想在其中搜索一个文章编号,但结果不能依赖于点、逗号等特殊字符。

我正在使用这样的查询:

 SELECT * FROM `table`
 WHERE 
 replace(replace(replace( replace( `haystack` , ' ', '' ),
 '/', '' ), '-', '' ), '.', '' )
 LIKE 'needle'

这种方法非常非常慢。 tablehaystack 上有一个索引,但是 EXPLAIN 显示查询不能使用它,这意味着查询必须在 3.8 秒内扫描 1760 万行。

查询在一个页面中运行多次 (10-15x),因此页面加载速度极慢。

我该怎么办?在查询中使用替换是个坏主意吗?

最佳答案

当您对表中的实际数据进行替换时,MySQL 无法使用索引,因为它没有替换结果的任何索引数据需要与 指针进行比较

也就是说,如果您的替换设置是静态的,那么对数据进行非规范化并添加一个新列(如 haystack_search)可能是个好主意,其中包含应用了所有替换的数据。此列可以在 INSERTUPDATE 期间填充。然后可以有效地使用此列上的索引。

请注意,您可能希望在 LIKE 查询中使用 %,否则它实际上与普通的相等比较相同。现在,如果您使用像 %needle% 这样的搜索项(即带有变量 start),MySQL 将再次无法使用索引并回退到表扫描,因为它只能在以下情况下使用索引它看到搜索词的固定开头,即类似 needle% 的内容。

所以最后,您可能最终不得不调整您的数据库引擎,以便它可以将表保存在内存中。 MyISAM 表(或 MySQL 5.6 及更高版本以及 InnoDB 表)的另一种替代方法是使用 fulltext索引您的数据,这再次允许相当有效的搜索。

关于mysql - 大 MySQL 表,REPLACE -> 非常慢的查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19807716/

相关文章:

mysql - MyISAM 的 Django 外键完整性

mysql - 如何锁定单行

php - 使用 WHERE 子句加速 MySQL (MyISAM) 计数

mysql - MyISAM 表索引文件经常崩溃!

php - 使用 cakephp 3 从不同的数据库中检索关联模型

MYSQL MyIsaM 如何Join 2语句select + select count

mysql - 优化更新语句

mysql - 子查询引用父查询中的字段

mysql - 如何在 'IF' 语句中使用 'SELECT' 并在 mysql 上插入

mysql - 奇怪的 1264 超出范围错误