mysql Concat vs OR

Posted

技术标签:

【中文标题】mysql Concat vs OR【英文标题】: 【发布时间】:2014-09-13 08:15:05 【问题描述】:

我试图找到在多个列中搜索单词出现的最佳方法。当然,一个选项是在查询中添加多个OR

SELECT * FROM table WHERE column1 LIKE %term1% OR column2 LIKE %term1% OR......

但我虽然这使查询变得很长,尤其是当有多个术语时

在我的搜索中,我发现了 mysql 中的 CONCATfunction。这似乎允许我在连接列后进行一次搜索(对吗?):

SELECT * FROM table WHERE CONCAT(column1,column2,....) LIKE %term1% OR CONCAT(column 1,column2,...) LIKE %term2% ....

这具有更易于阅读和维护的优势

因为我还没有完全理解CONCAT的完整用法我不知道或者这是一个正确的使用方式。我想知道实现此搜索的正确和最有效的方法是什么。 (注意:我还计划按照这个 *** 问题中所述对其进行排序:mysql SORT BY amount of unique word matches,可能在使用这种方法时会出现问题?)

编辑:

也许只解释我的最终愿望会更容易:在 php 中,我有一个单词数组。我希望从我的数据库中选择所有行,其中 1 个单词出现在多个 colmun 之一中,然后按相关性对它们进行排序(甚至为某些列添加额外的重要性)。 (请注意,只有几千(少于 5000)行要搜索)

【问题讨论】:

有趣。在任何一种情况下,查找匹配行都会很慢(因为由于 LIKE 中的前导通配符,它​​不会使用索引)。这可能意味着对长字符串执行单个like 可能会更快。不利的一面是,如果您搜索术语 ME if 还会找到 column1 以 M 结尾且 column2 以 E 开头的行 @Kickstart : 如果通配符被跳过怎么办? ME问题可以通过concat_ws解决,不是吗? 我会坚持第一个选项,但我没有什么可以支持我的观点,除非你可能会得到错误的结果。例如:第 1 列:Rapido,第 2 列:太好了,您最终会得到 RapidoGreat,并且您将匹配“狗”。 Concat_ws 修复它,直到用户碰巧搜索包含您选择使用的分隔符的字符串。前导通配符的问题是 MySQL 不能使用索引来查找它们(它可能可以使用尾随通配符)。如果没有前导通配符,则使用大量 OR 将允许使用索引,但将字段连接在一起将确保仍需要前导通配符。 帖子末尾的“按相关性排序”会立即导致“全文”作为解决方案。这就是它的意图。但是如果你不能使用它,因为你的 InnoDB 版本不支持它是的 - 那么,好的,最好的建议:将你的 MySQL 服务器升级到 5.6。否则,您将始终围绕着这种神秘的解决方案。从性能的角度来看OR LIKE可能使用索引,但这不能保证,通常情况下不会。因此,双向方式很糟糕,唯一重要的可能是可读性。这是您的决定。 【参考方案1】:

最好的方法是使用全文搜索引擎来完成这项任务,或者使用 MySQL 的全文功能。

你可以在这里找到更多的解释: fulltext-natural-language

【讨论】:

但是使用INNOdb表并且不确定正在使用mysql 5.6,这个不能用 在这种情况下 - 使用外部全文搜索引擎。 我好像还没有听说过。你能解释一下吗? 您可以使用外部全文引擎,例如 Solr、Sphinx 或 Elasticsearch。然后,您应该使用一个键定义每 X 分钟从数据库中提取数据的查询。并在那里执行所有搜索,而不是在 mysql 中。【参考方案2】:

因为我认为这是一个有趣的观点,所以我认为最好尝试一下。

好吧,在您编辑之后,您似乎没有那么多数据,但我还是会发布结果:


编辑:这是我第一次尝试 MySQL 测试,正如@Alma Do 所说,这些结果“可能只是波动”。


第一个查询(90000 行)roadroad2VARCHAR(100)

SELECT * FROM adress WHERE CONCAT(road1,road2) LIKE '%test%'; 0.0503 秒

SELECT * FROM adress WHERE road1 LIKE '%test%' OR road2 LIKE '%test%'; 0.0710 秒

看起来确实多个LIKE 更足智多谋。我对MySQL资源验证不是很擅长,所以我没有继续深入,估计它仍然应该提供一个想法。

我看到的主要问题是CONCAT 是否会创建错误的匹配项:

SELECT CONCAT('fooa','bfoo')LIKE '%ab%' 可以工作,而 'fooa' LIKE '%ab% OR 'bfoo' LIKE '%ab% OR 不能。

对于 500 行,我认为您不会遇到资源问题,所以我会选择“具有更易于阅读和维护的优势”。

希望对你有帮助

【讨论】:

这些测量值只是几乎毫无意义的数字。实际情况可能取决于许多情况。例如,第一列可能总是包含所需的单词,因此,第二个LIKE 将永远不会被执行(短路)。或者,否则,如果第一列不包含该单词,则将为每一行执行两个LIKE。唯一合适的点是 - 单词重叠边缘情况,但这可以通过使用分隔符来修复。但是,90.000 也太小了,无法在测试结果中认真看待。 0.01..0.05 秒可能只是波动。 感谢提示,这实际上是我第一次尝试做一些 MySQL 测试,想看看我是否可以做点什么,但事实上,很多细节开始成为问题.. . 我相信他们可能确实没有那么精确,但是,希望它仍然可以帮助:) 对我来说已经足够了? 为“更易于阅读和维护”点赞! 顺便问一下:看看能不能用CONCAT_WS代替CONCAT。

以上是关于mysql Concat vs OR的主要内容,如果未能解决你的问题,请参考以下文章

markdown Concat_vs_Merge

Pandas DataFrame concat vs append

Java:String concat vs StringBuilder - 优化了,我该怎么办?

MySQL 中 concat 函数

mysql函数concat与group_concat使用说明

mysql concat和group concat的区别