大MySQL表,REPLACE - >查询速度很慢

时间:2013-11-06 09:01:22

标签: mysql myisam

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

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

我正在使用这样的查询:

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

这种方法非常慢。 table的索引位于haystack,但EXPLAIN显示查询无法使用,这意味着查询必须扫描1760万行 - 在3.8秒内。

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

我该怎么办?在查询中使用replace是不是一个坏主意?

3 个答案:

答案 0 :(得分:0)

您可以尝试在列上使用LENGTH,但不确定它是否会产生更好的效果。此外,使用LIKE时,您应该使用%

SELECT * FROM `table`
WHERE 
haystack LIKE 'needle%' AND
LENGTH(haystack) - LENGTH(REPLACE(haystack,'/','')) = 0 AND
LENGTH(haystack) - LENGTH(REPLACE(haystack,'-','')) = 0 AND
LENGTH(haystack) - LENGTH(REPLACE(haystack,'.','')) = 0;

如果干草堆完全是针,那就这样做

SELECT * FROM `table`
WHERE 
haystack='needle';

答案 1 :(得分:0)

将函数应用于列是“不好的”,因为它会强制扫描列。

也许这是一种更好的方法:

SELECT list
     , of
     , relevant
     , columns
     , only
FROM   your_table
WHERE  haystack LIKE 'two[ /-.]needles'

在这种情况下,我们正在寻找“两针”,其中单词之间的空格可以是方括号内的任何字符,即“两针”,“两针/针”,“双针”或“ two.needles”。

答案 2 :(得分:0)

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

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

请注意,您可能希望在UPDATE查询中使用%,因为它实际上与普通的相等比较相同。现在,如果您使用像LIKE这样的搜索项(带有变量start),MySQL再次无法使用索引并回退到表扫描,因为只有在看到固定的启动时它才能使用索引搜索字词,例如%needle%

因此,最后,您可能最终必须调整数据库引擎,以便它可以将表保存在内存中。使用MyISAM表(或使用MySQL 5.6及更高版本的InnoDB表)的另一种方法是在数据上使用fulltext索引,这又可以进行相当有效的搜索。