当前位置: 首页 > 编程语言 > C#

如何优化MySQL布尔全文搜索?(或者用什么代替?)-C#分享

时间:2023-04-10 12:06:05 C#

如何优化MySQL布尔全文搜索?(或者用什么替换它?)-C#我有一个大约有22000行的表,我使用布尔全文搜索来查找我感兴趣的内容。我的问题是我创建了一个“动态搜索感觉”,其中包含在每个TextChanged事件后刷新的DataGridView。正如您可能想象的那样,在每个事件之后搜索插入的字符串需要花费大量时间。我可以做些什么来提高搜索速度?欢迎任何建议!首先,您应该知道RDBMS对全文索引的支持是一种强制技术,旨在允许高效访问结构化数据以处理非结构化文本。(是的,这只是我的意见。如果需要我可以保护它,因为我非常了解这两种技术。;)那么,可以做些什么来提高搜索性能呢?场景一-“任务的最佳工具”处理文档语料库中的全文搜索的最佳方法是使用专门设计用于它们的技术,例如来自Apache的SOLR(Lucene)或来自err的Sphinx,Sphinx。我强烈推荐这种方法,原因将在下面阐明。选项二-预加载结果在构建基于文本的搜索解决方案时,通常的方法是将所有文档索引到一个可搜索的索引中,虽然这可能是最方便的方法,但并不是唯一的方法。假设您正在搜索的内容可以很容易地量化为一组已知的规则,那么您可以提供一种比不合格的全文搜索更具“指导性”的搜索方式。我的意思是,如果您的应用程序可能受益于将用户指向结果,您可以根据一组已知规则将各种结果集预加载到它们自己的表中,从而减少要搜索的大量数据。如果您希望大多数用户以已知顺序从一组已知搜索词中受益,您可以构建搜索UI以支持这些词。因此,假设大多数用户正在寻找各种汽车,您可以提供基于型号、年份、状况等的预定义搜索。您的搜索UI将被设计为一系列下拉菜单,以“引导”用户到特定结果。或者,如果大多数搜索针对的是特定主题(例如“汽车”),您可以预定义一个表,其中仅包含您之前确定为与汽车相关的记录。这两种方法都减少了要搜索的记录数,从而增加了响应时间。选项三——“自己动手”如果您无法将外部搜索技术集成到您的项目中并且预加载不是一种选择,仍然有很多方法可以大大缩短搜索查询响应时间,但它们会根据您需要完成的任务而有所不同以及您执行搜索的方式各不相同。如果您希望用户使用单个关键字或短语以及它们之间的布尔关系进行搜索,您可以考虑构建自己的语料库“倒排索引”。(这是MySQL的布尔全文搜索已经做的,但是你自己做可以让你更好地控制搜索的速度和准确性。)从现有数据构建倒排索引:步骤1.创建三个表//dict-语料库中每个唯一单词对应一行的字典createtabledict(idintprimarykey,wordvarchar)//反转-使用inverted_index将单词映射到语料库中的记录createtableinvert(idintprimarykey,rec_idint,word_idint)//停用词-包括索引时要忽略的词(如a、an、the等)创建表停用词(idint主键,wordvarchar)注意:这只是一个草图。在实际创建这些表时,您需要添加索引和约束等。停用词列表用于将索引的大小减少到仅对用户的预期查询很重要的词。例如,索引英语文章(如“a”、“an”、“the”)很少有用,因为它们不会为关键字搜索提供有用的含义。通常,您需要专门为您的应用程序需求制作的停用词列表。如果您不希望用户在他们的查询中包含术语“red”、“white”或“blue”,或者如果这些术语出现在每个可搜索记录中,您可能希望将它们添加到您的停用词列表中。请参阅此消息末尾的注释,了解有关在MySQL中使用您自己的停用词列表的说明。另请参阅:步骤2。构建倒排索引要从现有记录构建倒排索引,您需要(伪代码):foreach(word(w)(r)inrecord){if(wisnotastopword){if(wisnotindictionaryexists){insertwintodictionaryonw.id}insert(r.id,w.id)intoinverted_index}}关于停用词的更多信息:不用使用特定的停用词列表,'if(wisnotstopwordswords)'测试可以做出其他决定,而不是作为不可接受单词列表的附件。您的应用程序可能希望过滤掉所有长度少于4个字符的单词,或者仅包含预定义集中的单词。通过创建自己的倒排索引,您可以获得更大更细粒度的搜索控制。第3步。使用SQL查询倒排索引这一步实际上取决于您希望如何将查询提交给索引。如果查询是“硬编码的”,您可以自己创建select语句,或者如果您需要支持用户输入的查询,则需要将您选择的任何查询语言翻译成SQL语句(通常使用简单的解析器).假设您希望检索与逻辑查询“(word1ANDword2)或word3”匹配的所有文档,一种可能的方法是:反转为I,dict为DWHEREI.word_id=D.idAND(D.word='word1'ORD.word='word2')GROUPBYI.rec_idHAVINGcount=2)UNION(SELECTrec_id,1AScountFROMinvertASI,dictASDWHEREI.word_id=D.idANDD.word='word3');从temp_results选择不同的rec_id;删除表temp_results;注意:这只是我脑海中的第一次传球。我相信有更有效的方法可以将布尔查询表达式转换为高效的SQL语句,并欢迎提出任何改进建议。要搜索一个短语,您将向倒排索引添加一个字段以指示该词在其记录中出现的位置,并在您的SELECT中对其进行计数。最后,当你添加新记录或删除旧记录时,你需要更新倒排索引。最后一句“全文检索”属于一个非常大的研究领域,称为“信息检索”或IR,有很多关于这个主题的书籍,包括查看亚马逊关于如何在MySQLWordLists中使用自己的停用的更多信息说明要在MySQL中使用您自己的停用词列表:创建您自己的停用词列表,每行一个词,并将其保存到服务器上的已知位置,例如:/usr/local/lib/IR/stopwords.txt编辑我的.cnf添加或更新以下行:[mysqld]ft_min_word_len=1ft_max_word_len=40ft_stopword_file=/usr/local/lib/ir/stopWords.txt它将设置最小和最大合法字数长度分别设置为1和40,并告诉mysqld在哪里可以找到自定义停用词列表。(注意:默认的ft_max_word_len是84,我觉得过大了,可能会导致非真实的词串运行被索引。)重启mysqld以上是C#学习教程:如何优化MySQL布尔全文搜索?(或者用什么代替?)–C#分享的所有内容,如果对你有用,需要了解更多C#学习教程,希望大家多多关注–删除并重新创建所有索引相关全文本文来自网络收藏,不代表立场,如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: