如何加速使用LIKE%...%的HAVING

时间:2015-01-23 14:26:23

标签: mysql sql having

我们的查询需要30秒。当我们删除这个HAVING子句时,需要1秒钟:

HAVING (group_concat(DISTINCT service.service ORDER BY 
service.service ASC SEPARATOR ",") like "%translation%")
ORDER by fqa_value DESC
LIMIT 0,10;

字段service.service是一个ENUM,其中一个项目是“translation”。

是否有更有效的方法来构建此HAVING而不构建逗号分隔的字符串,然后在其中搜索文本,如下所示:

HAVING ("translation" IN (DISTINCT service.service ORDER BY service.service))
ORDER by fqa_value DESC
LIMIT 0,10;

4 个答案:

答案 0 :(得分:1)

仅供参考,此HAVING子句中存在逻辑错误:

HAVING (group_concat(DISTINCT service.service ORDER BY service.service ASC SEPARATOR ",") like "%translation%")

这会匹配atranslationbtranslation等内容,因为您没有明确匹配起始逗号。你想要更像这样的东西(条款周围的括号是多余的):

HAVING CONCAT(',', group_concat(DISTINCT service.service ORDER BY service.service ASC SEPARATOR ","), ',') like "%,translation,%"

或者这个:

HAVING 'translation' REGEXP CONCAT('^(', group_concat(DISTINCT service.service ORDER BY service.service ASC SEPARATOR '|'), ')$')

但是,我认为其中任何一项都不会对您的表现有很大帮助。相反,您可能会做的是以下内容:

SELECT mykeycolumn, fqa_value, GROUP_CONCAT(DISTINCT service.service ORDER BY service.service ASC SEPARATOR ",")
  FROM service s1
 WHERE EXISTS ( SELECT 1 FROM service s2
                 WHERE s2.mykeycolumn = s1.mykeycolumn
                   AND s2.service = 'translation' )
 ORDER BY fqa_value DESC
 LIMIT 0,10;

其中mykeycolumn是您的主键列。

答案 1 :(得分:0)

由于您的LIKE以通配符开头,因此您将不得不从根本上改变您的方法。当你进行全文搜索时,MySQL无法索引数据。

如果你可以改变表格:

将枚举拆分为bool-columns(每个可能的枚举值一个)并对其进行索引。这是你比O(n)更快的唯一方法。

答案 2 :(得分:0)

"翻译" IN(DISTINCT service.service ORDER BY service.service) " DISTINCT"和"订购"不是相关的,应该被丢弃。

我做了类似你正在尝试的事情,但是我创建了一个额外的字段并将所有可搜索的字段插入其中,然后搜索该字段。

你必须返回并更改(添加到)你的表,写一个触发器,但它应该为你做的伎俩

答案 3 :(得分:0)

如果删除HAVING子句,您可能会发现性能会更好,而是使用现有的连接条件将另一个连接(在另一个别名下)添加到Services表中,并附加标准{ {1}}。