【问题标题】:SQL full text search vs "LIKE"SQL全文搜索与“LIKE”
【发布时间】:2010-10-03 11:16:55
【问题描述】:
假设我有一个相当简单的应用程序,它允许用户在他们拥有的 DVD 上存储信息(标题、演员、年份、描述等),我希望允许用户通过这些字段中的任何一个搜索他们的收藏(例如“ Keanu Reeves”或“The Matrix”将是有效的搜索查询)。
使用 SQL 全文搜索与简单地用空格分割查询并在 SQL 语句中执行一些“LIKE”子句相比有什么优势?它只是表现更好还是实际上会返回更准确的结果?
【问题讨论】:
标签:
sql
database
full-text-search
【解决方案1】:
全文搜索可能会更快,因为它将受益于用于查找记录的单词索引,而使用 LIKE 则需要进行全表扫描。
在某些情况下,LIKE 会更准确,因为 LIKE "%The%" AND LIKE "%Matrix" 会选择 "The Matrix" 而不是 "Matrix Reloaded",而全文搜索将忽略 "The" 并返回两者。也就是说,两者都可能是一个更好的结果。
【解决方案2】:
全文索引(即索引)比使用 LIKE(基本上每次都检查每一行)要快得多。但是,如果您知道数据库会很小,则可能没有性能需要使用全文索引。确定这一点的唯一方法是进行一些智能平均,并根据该信息进行一些测试。
准确性是一个不同的问题。全文索引允许你做几件事(加权、自动匹配吃/吃/吃等),你不可能在任何合理的时间范围内使用 LIKE 实现它。真正的问题是您是否需要这些功能。
如果不阅读这些功能的全文文档描述,您真的不知道应该如何进行。所以,请阅读!
此外,一些基本测试(在表格中插入一堆行,可能使用某种公共词典作为词源)将大大帮助您做出决定。
【解决方案3】:
全文搜索查询要快得多。尤其是在处理不同列中的大量数据时。
此外,您还将获得特定语言的搜索支持。例如。当存储为“ueber”时,也会发现像“über”中的“ü”这样的德语变音符号。您还可以使用同义词来自动扩展搜索查询,或者替换或替换特定短语。
在某些情况下 LIKE 会更准确
因为喜欢“%The%”和喜欢“%Matrix”
会选择“黑客帝国”,但不会
“Matrix Reloaded” 而全文
搜索将忽略“The”并返回
两个都。也就是说,两者都可能有
结果更好。
这是不正确的。全文搜索语法允许您指定搜索的“方式”。例如。通过使用CONTAINS 语句,您可以使用精确术语匹配以及模糊匹配、权重等。
因此,如果您遇到性能问题或希望提供更“类似于 Google”的搜索体验,请选择全文搜索引擎。它也很容易配置。
【解决方案4】:
只是一些注意事项:
如果您的 LIKE 不以 % 开头,LIKE 可以使用索引搜索。示例:LIKE 'Santa M%' 很好! LIKE '%Maria' 不好!并且可能导致表或索引扫描,因为这无法以标准方式建立索引。
这非常重要。全文索引更新是异步的。例如,如果您在一个表上执行 INSERT,然后执行带有全文搜索的 SELECT,您希望新数据出现在该处,您可能不会立即获得数据。根据您的配置,您可能需要等待几秒钟或一天。通常,当您的系统没有很多请求时,会填充全文索引。
【解决方案5】:
它的性能会更好,但除非您有大量数据,否则您不会注意到这种差异。 SQL 全文搜索索引允许您使用比简单的“LIKE”操作更高级的运算符,但如果您所做的只是对全文索引执行 LIKE 操作,那么您的结果将是相同的。
【解决方案6】:
想象一下,如果您允许在 DVD 上输入注释/描述。
在这种情况下,最好允许按描述进行搜索。
在这种情况下,全文搜索会做得更好。
【解决方案7】:
您可能会得到稍微好一点的结果,或者至少可以更轻松地实现全文索引。但这取决于您希望它如何工作...
我的想法是,如果您要搜索两个单词,那么您必须使用 LIKE 手动实现(例如)一种方法来加权列表中较高的单词。全文索引应该为您完成此操作,并允许您使用相关语法来影响权重。
【解决方案8】:
到 SQL Server 中的 FullTextSearch 为 LIKE
首先,您必须创建一个StopList 并将其分配给您的表
CREATE FULLTEXT STOPLIST [MyStopList];
GO
ALTER FULLTEXT INDEX ON dbo.[MyTableName] SET STOPLIST [MyStopList]
GO
其次,使用下面的tSql脚本:
SELECT * FROM dbo.[MyTableName] AS mt
WHERE CONTAINS((mt.ColumnName1,mt.ColumnName2,mt.ColumnName3), N'"*search text s*"')