我有一个简单的数据库表,存储id,语言和文本。我想做一个搜索任何单词/字符,并寻找一个完全匹配。问题是我有超过1000万行。
。搜索单词I将返回文本中包含" I "比如"信息不好"。和"我喜欢狗"。
这也需要适用于停止词和其他不使用空格的语言。
我的第一个直接的想法是只是做LOWERCASE(text) LIKE %word%
小写索引的文本,但在谷歌搜索后,它似乎会做一个完整的表扫描,我正在使用planetscale,所以我必须支付一个完整的表扫描,这根本不能工作,因为我将耗尽使用快。
我的下一个想法是布尔全文搜索,但后来我遇到了在英语中被忽略的停止词的问题,并且必须使用像中文这样的语言的ngram解析器,然后必须计算出提交的语言和应该使用的索引。
谁有更好的主意?- 使用
CHARACTER SET utf8mb4
- 为该字符集使用最新可用的
COLLATION
-utf8mb4_unicode_520_ci
或utf8mb4_0900_ai_ci
或其他用于最新的MariaDB。 - 不要使用
LOWERCASE
或LOWER
(等等),相反,让排序规则来处理这些(注意"ci"> - 是的,对于某些亚洲语言,您可能需要ngram而不是
FULLTEXT
。 - 停车牌可以关闭
- 最小字长是可以改变的,但要付出代价。
- 你的应用程序代码可以查看编码来决定是否使用全文的ngram。
- 这提供了一个十六进制值的列表:http://mysql.rjweb.org/doc.php/charcoll#diagnosing_charset_issues注意,E3-EA大多是"无字"的;语言。
- 我建议使用应用程序代码进行决策和构建SQL查询。在某些情况下,它甚至可能退化为
LIKE '%word%'
或REGEXP '\bword\b'
。请注意,REGEXP通常比LIKE慢,但提供了"词边界";测试搜索字符串是否包含多个单词。 - 当适用时,
FULLTEXT
比任何其他技术都要快得多。 - 当执行
WHERE ... AND MATCH ...
时,匹配将首先执行,即使WHERE的其余部分更具选择性。 LIKE '%...'
和所有(?)REGEXP
测试会。读取并测试你的每一个10M行(除非有LIMIT
)。