左大加权快速搜索大文本数据集 - Mysql

时间:2017-12-04 05:30:45

标签: mysql database query-optimization

我有一个大型数据集,我想在mysql上用于自动完成(> 1M记录)。

作为一个例子,我正在打字"甲醇"并希望提出类型建议..

目前我有

select AgentReferenceName as name
from tblAgentReference 
where AgentReferenceName like '%methan%' 
order by instr(AgentReferenceName,'methan'), char_length(AgentReferenceName) 
limit 10;

这很好地完成了工作,但是有点慢

+-------------+
| name        |
+-------------+
| Methan      |
| Methane     |
| Methane     |
| Methane     |
| Methanal    |
| Methanol    |
| Methanol    |
| Methanide   |
| Methanamine |
| Methanamine |
+-------------+
10 rows in set (3.52 sec)

我在该字段上有全文索引,但是当我运行通常的全文加权搜索时 - 它会碰到更大的单词,所以我得到了

select AgentReferenceName as name  from tblAgentReference  where match(AgentReferenceName) against ('methano*' in boolean mode)   order by match(AgentReferenceName) against ('methano*') limit 10;     
+----------------------------------------------------------------------------------------------------------+
| name                                                                                                     |
+----------------------------------------------------------------------------------------------------------+
| 2,4-Methanoacridin-9-amine, 8-fluoro-1,2,3,4-tetrahydro-, 2-hydroxy-1,2,3-propanetricarboxylate (3:2)    |
| 9-Amino-8-fluoro-1,2,3,4-tetrahydro-2,4-methanoacridine                                                  |
| 9-Amino-8-fluoro-1,2,3,4-tetrahydro-2,4-methanoacridine                                                  |
| 2,4-Methanoadamantane                                                                                    |
| 2,4-Methanoadamantane                                                                                    |
| 2-Amino-4,5-methanoadipate                                                                               |
| 1,4-Methanoanthra(2,3-c)oxepin-7,12-dione, 1,3,4,5-tetrahydro-4,6,13-trihydroxy-3,11-dimethoxy-3-methyl- |
| 1,4-Methanoanthracene-9,10-dione, 1,2,3,4-tetrahydro-                                                    |
| 1,4-Methanoanthracene-9,10-dione, 1,2,3,4-tetrahydro-                                                    |
| 1,4-Methanoanthracene-9,10-dione, 1,2,3,4,4a,9a-hexahydro-                                               |
+----------------------------------------------------------------------------------------------------------+
10 rows in set (0.13 sec)

所以速度很好,但结果很糟糕

我的问题 - 如何进行类似查询的快速搜索,但更接近全文的速度?

2 个答案:

答案 0 :(得分:0)

(一些随意的想法......)

WHERE MATCH(...) AGAINST(...)
  AND ... LIKE ...

首先使用FULLTEXT进行 过滤,然后通过LIKE进一步过滤。

但是...我对您当前的代码感到困惑。第一个示例(使用instr趋势从“Methan”开始选择数据。使用

可以更有效地执行此操作
AgentReferenceName LIKE 'Methan%'

假设你有INDEX(AgentReferenceName). If AgentReferenceName is TEXT and not VARCHAR`,那么请考虑一个只有短名称索引的额外列。

然后考虑

( SELECT ... WHERE ... LIKE 'Methan%' ... LIMIT 10 )
UNION DISTINCT
( SELECT ... WHERE MATCH ... LIMIT 10 )

这将为您提供最多20行进行进一步排序(并削减至10行) - 可能在应用程序代码中。

答案 1 :(得分:0)

我已经处理了这个确切的问题。这就是我的所作所为。

当用户提供的自动完成字符串长度为一个或两个字符时,请忽略它。不要尝试自动填充(除非您有用户以前的搜索记录)。

当用户提供的自动填充字符串相对较短(尝试六个字符)时,请使用WHERE name LIKE CONCAT(:userstring, '%'),从而根据用户的需要搜索字符串开始。那可以利用索引。用户可以找到她想要的字符串并选择它,然后你就完成了。

如果用户提供的字符串较长,请使用WHERE name LIKE CONCAT('%', :userstring, '%')的其他查询。只有较长的字符串才会使用前导%提供性能查杀功能。性能仍然会很糟糕,但该功能的使用频率会降低。

你最好的选择是,就像Rick James提到的那样,创建一个包含开始字符串的表格,其中包含您最常期望的搜索词。然后,您始终可以使用LIKE 'searchterm%'并完全避免使用%

当您使用自动完成时,FULLTEXT已经发现了一些限制。