搜索MySQL中varchar列的最快方法

时间:2015-12-29 08:41:44

标签: regex search tags sql-like divide

我想为书店实施搜索查询。我使用MySQL并且我有一个varchar列,其中包含姓名,作者或其他详细信息,例如The Tragedy of Hamlet, Prince of Denmark, by William Shakespeare,我希望像shakespeare tragedydenmark tragedy一样搜索,以便将书籍列入其中一栏。

我有三个问题要实现,但我想知道他们的表现。

LIKE %%

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

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

但有人告诉我like是一个慢速运算符,特别是2%因为它不能使用索引。

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

但我被告知relational division也是如此之慢。

REGEXP

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

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

但是有人告诉我它比LIKE

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

1 个答案:

答案 0 :(得分:2)

当然使用内置操作数的LIKE,比正则表达式更优化。但是这里有一个重点是你无法将这两个配方进行比较,因为LIKE用于向字符串添加通配符,而正则表达式用于根据可能非常复杂的模式匹配字符串。

无论如何,我想到这个目标的最佳方式将是以下之一:

  1. 在已正确编入索引的列上使用LIKE 1
  2. 使用一些优化的搜索技术,例如elastic search
  3. 实现多线程算法 2 ,它在IO任务中表现非常好。对于这个,您可以使用一些技巧,例如定义偏移量并在线程之间划分表格。
  4. 另外,对于某些替代方法,请阅读本文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?