如何搜索文字? (MySQL的)

时间:2015-04-17 09:33:50

标签: mysql sql search

我有这张桌子:

bussId    |      nameEn        |          keywords
  500          name1 name2             keyword1 keyword2

如果用户搜索(keyword1或keyword2或name2或name1),我想返回bussId 5000。 所以我应该使用这个查询SELECT * FROM business WHERE nameEn LIKE '%searched_word%'。 但根据Comparison of B-Tree and Hash Indexes&#34,此查询不使用index nameEn or keywords;如果LIKE的参数是常量字符串,则该索引也可用于LIKE比较不以通配符开头#34;。

我有这个解决方案,我想创建另一个表并插入所有单词:

bussId |  word
  500        name1
  500        name2
  500        keyword1
  500        keyword2

然后我将使用此查询搜索bussId:
SELECT * WHERE word LIKE 'searched_word%'.

通过这种方式,我将确保MySQL将使用索引,并且它会更快,但是这个表将包含大约2000万行!

还有其他解决方案吗?

5 个答案:

答案 0 :(得分:6)

您必须使用MyisAM或InnoDB从MySQL 5.6开始使用全文索引:

mysql> ALTER TABLE business ADD FULLTEXT(nameEn, keywords);

以下是您的要求:

mysql> SELECT * FROM business
   -> WHERE MATCH (nameEn, keywords) AGAINST ('searched_word');

答案 1 :(得分:0)

您是否尝试过Instr()或Locate()函数?这是SO discussion将它们与Like进行比较,但可能比前面的%通配符更好。它仍然运行全表扫描,但不知道MySQL查询优化器如何使用字符串函数进行索引。

SELECT * FROM business WHERE Instr(nameEN, 'search_word') > 0 

OR

SELECT * FROM business WHERE Locate(nameEN, 'search_word') > 0 

此外,可能还有其他优化领域。查看business表中是否有其他可能的索引,如果未使用所有列,则显式声明特定列而不是星号(*),并解析nameENkeywords列通过空格使列保留一个值(可以转置),然后使用隐式连接WHERE或显式连接JOIN。这甚至可能是一个表设计问题,存在在单个字段中存储多个值的挑战。

答案 2 :(得分:0)

使用新版本的MySQL你不需要制作引擎“MyISAM”,InnoDB也支持FULLTEXT索引(我已经测试了这个5.6.15,支持表单版本> = 5.6.4)。 因此,如果您的服务器版本高于5.6.4,则只需将FULLTEXT索引添加到您的表中,并使用MATCH(...)AGAINST(...)进行选择,下面的示例

CREATE FULLTEXT INDEX idx ON business (nameEn);

SELECT * FROM business 
WHERE match(nameEn)against('+searched_word' IN BOOLEAN MODE);

答案 3 :(得分:0)

在MySQL或SQL中使用以下语句,它将返回完美结果:

SELECT * FROM business WHERE (nameEn LIKE 'searched_word%' OR nameEn LIKE '%searched_word%') OR (keywords LIKE 'searched_word%' OR keywords LIKE '%searched_word%') AND bussID = 500;  

这应该有用。

答案 4 :(得分:0)

2000万条记录非常多,带有varchar列的映射表将为每行分配最大允许字符数字+ 32位整数列。

如果您可以创建一个像(id int,crc int)这样的表并仅存储文本数据的crc32值,该怎么办?它区分大小写,因此您需要在填充数据时转换为大写/小写,并在比较时进行相同的转换。

我同意全文方法,但为了节省空间并利用索引的优势,您可以尝试下面的内容。

Create Temporary TABLE t (id INT, crc INT);

Insert Into t
Select 500, CRC32(UPPER('name1'))
Union Select 500, CRC32(UPPER('name2'))
Union Select 500, CRC32(UPPER('keyword1'))
Union Select 500, CRC32(UPPER('keyword2'));

Select * From t Where crc = CRC32(UPPER('keyword2');