全文索引缓慢。寻找替代品

时间:2013-02-28 15:41:17

标签: performance sql-server-2008 jquery autocomplete full-text-search

我有一张表,我已经创建了一个全文目录。该表只有6000多行。我在索引中添加了两列。第一个可以被认为是排序的唯一标识符,第二个可以被认为是该项目的内容(我的表中有11个其他列不是全文目录的一部分)。以下是几行的示例:

TABLE: data_variables
ROW    unique_id    label
1      A100d1       Personal preference of online shopping sites
2      A100d2       Shopping behaviors for adults in household

在前端的我的网络应用程序中,我有一个文本框,用户可以输入该文本框以获取与UNIQUE IDLABEL中搜索的任何字词匹配的项目列表} 列。因此,例如,如果用户输入shoa100,则列表将填充上面的两个行。如果他们输入behav,那么列表将仅填充上面的第2行。

这是通过每个keyup上的Ajax请求完成的。 PHP在SQL服务器上调用存储过程,如下所示:

SELECT TOP 50 dv.id, dv.id + ': ' + dv.label, 
              dv.type_id, dv.grouping, dv.friendly_label
FROM          data_variables dv
WHERE         (CONTAINS((dv.unique_id, dv.label), @search))

@search是传递给存储过程的用户文本。)

我注意到这种情况非常缓慢,特别是当我在查询中没有使用TOP 50时。

我正在寻找的方法是直接在SQL Server上加速,或者放弃全文索引的想法,并使用jQuery搜索客户端的可搜索项目数组。我看了一下jQuery AutoComplete的东西以及其他一些用于AutoComplete的jQuery插件,但还没有尝试模拟任何东西。这将是我的下一步,但我想先在这里查看,看看我会得到什么建议。

提前致谢。

5 个答案:

答案 0 :(得分:6)

除非你使用线性索引(从左到右)并且你正在进行LIKE 'work%'之类的查询,否则我会建议不要使用LIKE。如果您正在执行类似LIKE '%word%'的操作,则常规索引不会对您有所帮助。当您想要搜索段落中的单词时,通常需要使用全文索引。

对于大量数据,通常数据库中的内置全文引擎并不是非常盗取。为了获得最佳性能,您通常必须使用专为全文构建的外部解决方案。

有些选项是SphinxSolrelasticsearch,仅举几例。我不会说这些选项中的任何一个都比另一个更好。肯定有利有弊要考虑:

  • 你有什么样的数据?
  • 这些解决方案有哪些语言支持?
  • 这些解决方案支持哪些数据库引擎?

您可以做的最好的事情是根据现有数据对这些解决方案进行基准测试。测试每个单独的组件(单元测​​试)可以帮助您识别真正的问题并帮助您找到好的解决方案。

答案 1 :(得分:5)

几个建议,基于你只有6000行的事实,所以数据库应该活着吃这个。

一个。尝试使用Like运算符,以防它有所帮助。不要期待它,但尝试相当微不足道。这里还有其他一些东西让你发现,鉴于这些数量很小,这种情况很慢。

B中。你可以提前缓存查询吗?对于6000行,可能只有36 * 36个2个字符的查询组合,这几乎不需要内存,并且可以保存数据库的任何工作。

℃。将选择移出到客户端是一个好主意,取决于总体上6000行的大小,以及单个查找的网络延迟。

d。结合b和c将给你非常好的表现我怀疑,但需要一些编码工作。如果服务器维护缓存中所有单个字符结果的列表,并且客户端在第一次击键后下载字母缓存集,则它们可能具有所有行的子集,但不需要为额外的击键执行更多网络IO。 / p>

答案 2 :(得分:5)

我遇到了同样的问题并选择了LIKE解决方案。我发现,或者运算符过于繁重,并将查询分成两个选项,并且全部为union(最快,在我的场景中,无法在索引列和数据中找到相同的文本)。

你的就像

SELECT TOP 50 from (
select dv.id, dv.id + ': ' + dv.label, 
              dv.type_id, dv.grouping, dv.friendly_label
FROM          data_variables dv
WHERE         dv.unique_id like '%'+@search+'%'
UNION ALL
select dv.id, dv.id + ': ' + dv.label, 
              dv.type_id, dv.grouping, dv.friendly_label
FROM          data_variables dv
WHERE         dv.label like '%'+@search+'%' 
)

哦!并测试SQL Server中的性能,而不是Web!

答案 3 :(得分:2)

如果您计划增加数据量,最好使用反向索引进行全文搜索。

此时请查看Apache Solr - 最佳全文搜索引擎。

您可以简单地定期索引您的数据库数据并使用solr作为搜索引擎, 它提供简单的ajax api,可以直接从前端查询。

答案 4 :(得分:0)

如果你真的需要表演..你可能想看一下; FTS3和FTS4 ......

从另一个论坛发帖...

例如,如果“安全电子邮件数据集”中的每个517430文档都插入到FTS表和使用以下SQL脚本创建的普通SQLite表中:

代码: CREATE VIRTUAL TABLE enrondata1使用fts3(内容TEXT); / * FTS3表 / CREATE TABLE enrondata2(内容TEXT); / 普通表* / 然后可以执行以下两个查询中的任何一个以找到数据库中包含单词“linux”(351)的文档数。使用一台台式PC硬件配置,FTS3表上的查询大约返回0.03秒,而查询普通表则为22.5。

...见

http://www.sqlite.org/fts3.html