regex - 在 MySQL 中搜索 varchar 列的最快方法

标签 regex search tags sql-like divide

我想实现一个书店的搜索查询。我使用 MySQL,我有一个 varchar 列,其中包含姓名、作者或其他详细信息,例如威廉·莎士比亚的《丹麦王子哈姆雷特的悲剧》,我想像莎士比亚悲剧一样进行搜索code> 或 丹麦悲剧 列出书籍列表,将它们放在一列中。

我有三个查询来实现此目的,但我想了解它们的性能。

喜欢%%

我的第一种方法是将搜索文本拆分为单词并根据字数创建动态命令:

SELECT * FROM books
WHERE name LIKE '%shakespeare%'
AND name LIKE '%tragedy%'

但我被告知 like 是一个慢操作符,特别是两个 %,因为它不能使用索引。


TAG表和关系划分

我的第二种方法是使用另一个包含以下标签的表:

-------------------------
| book_id |    tag      |
|-----------------------|
|    1    | Tragedy     |
|    1    | Hamlet      |
|    1    | Prince      |
|    1    | Denmark     |
|    1    | William     |
|    1    | Shakespeare |
-------------------------

并创建动态除法命令:

SELECT DISTINCT book_id FROM booktag AS b1 
WHERE ((SELECT 'shakespeare' as tag UNION SELECT 'tragedy' as tag)
       EXCEPT
       SELECT tag FROM booktag AS b2 WHERE b1.book_id = b2.book_id) IS NULL

但有人告诉我关系除法也太慢了。


正则表达式

我的第三种方法是使用正则表达式:

SELECT * FROM books
WHERE name REGEXP '(?=.*shakespeare)(?=.*tragedy)'

但是有人告诉我它比LIKE

请帮我决定哪种方式更快?

最佳答案

当然,使用内置操作数LIKE比正则表达式更优化。但这里有一个重要的点,您不能将这两个方法放在一起比较,因为 LIKE 用于向字符串添加通配符,而正则表达式用于基于可能非常复杂的模式匹配字符串。

无论如何,我想到的实现这一目标的最佳方法是以下之一:

  1. 对已正确索引的列使用 LIKE1
  2. 使用一些优化的搜索技术,例如 elastic search .
  3. 实现多线程算法2,该算法在 IO 任务中表现非常出色。对于这个,您可以使用一些技巧,例如定义偏移量并在线程之间划分表。

另外,对于一些替代方法,请阅读这篇文章 https://technet.microsoft.com/en-us/library/aa175787%28v=sql.80%29.aspx


<子> 1. 您应该小心在列上放置索引的方式。阅读此答案以获取更多信息 https://stackoverflow.com/a/10354292/2867928和这篇文章http://use-the-index-luke.com/sql/where-clause/searching-for-ranges/like-performance-tuning

<子> 2.阅读此答案以获取更多信息Multi Thread in SQL?

关于regex - 在 MySQL 中搜索 varchar 列的最快方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34507478/

相关文章:

search - 查找大文本中重复次数最多的短语

api - 有哪些工具可以找到搜索频率

regex - Grok 调试器和 Logstash grok 中的不同行为

regex - 多行正则表达式搜索和替换!

javascript - 如果月份无效,如何从 DOB 计算年龄?

python - 解析带有特殊标记的文本文件

html - 如何将html样式标签提取到css中

android - 如何在 Android Studio 中找到所有相关的硬编码字符串?

c++ - 在排序的字符串 vector 中进行有效搜索

Android jAudioTagger 问题 - 读取 mp3 文件 - VerifyError