改进mysql中的文件路径搜索

Dav*_*542 7 mysql sql unix search full-text-search

我需要搜索几百万个文件名.它们看起来像这样:

LG_MARGINCALL_HD2CH_127879834_EN.mov
Run Code Online (Sandbox Code Playgroud)

如果有人搜索以下任何内容,则应匹配:

  • 余量
  • 追加保证金
  • 保证金调用mov
  • 保证金通知hd en
  • margin call hd en mov

我目前使用的是一个mysql%LIKE%搜索.就像是:

SELECT filename FROM path WHERE filename LIKE '%margin%' AND filename LIKE '%mov%'
Run Code Online (Sandbox Code Playgroud)

这是非常慢的(搜索可能需要十秒钟).请注意,它确实有效.

什么是更好的方式来进行上述搜索?使用mysql或其他程序.

O. *_*nes 13

正如您所注意到的,您的搜索策略很慢.这很慢,因为

 LIKE '%something%'
Run Code Online (Sandbox Code Playgroud)

必须扫描表格才能找到匹配项.领先的LIKE搜索百分号是破坏性能的绝佳方式.

我不知道你的path表中有多少列.如果有很多列,您可以做两件快速的事情来提高性能:

  1. 摆脱SELECT *并列出结果集中所需列的名称.
  2. 创建一个复合索引,其中包含您的filename列,后跟您需要检索的其他列.

(如果您的表中只有几列,这将无济于事.)

你不能使用直接软件包FULLTEXT搜索这些东西,因为它是专为语言文本设计的.

如果我必须快速完成这项工作,我会这样做:

首先,创建一个名为"searchterm"的新表

 filename_id INT   the id number of a row in your path table
 searchterm  VARCHAR(20)  a fragment of a filename.
Run Code Online (Sandbox Code Playgroud)

其次,编写一个读取filename_idfilename值的程序,并为每个行插入一堆不同的行searchterm.对于您显示的项目,值应为:

LG_MARGINCALL_HD2CH_127879834_EN.mov   (original)
LG  MARGINCALL  HD2CH  127879834  EN  mov   (split on punctuation)
 HD 2 CH                                    (split on embedded numerics)
 MARGIN CALL                                (split on an app-specific list of words)
Run Code Online (Sandbox Code Playgroud)

所以,你的searchterm表中有一堆条目,都有相同的filename_id值和许多不同的小块文本.

最后,搜索时你可以这样做.

 SELECT path.id, path.filename, path.whatever,
        COUNT(DISTINCT searchterms.term) AS termcount
   FROM path
   JOIN searchterm ON path.filenanme_id = search.filename_id
  WHERE searchterm.term  IN ('margin','call','hd','en', 'mov')
  GROUP BY path.id, path.filename, path.whatever
  ORDER BY path.filename, COUNT(DISTINCT searchterms.term) DESC
Run Code Online (Sandbox Code Playgroud)

这个小查询找到所有匹配的片段到你要搜索的内容.它返回多个文件名,并按照与大多数术语匹配的顺序显示它们.

我建议您创建自己的应用程序特定类型全文搜索系统.如果你真的有几百万个多媒体文件,这肯定值得你努力.