优化mysql查询自动完成功能

时间:2015-03-07 23:04:38

标签: mysql full-text-search sql-like

我正在尝试优化用于从数据库中的字段进行自动完成的查询。我目前的尝试是使用like和外卡,但即使我添加了索引,查询也需要很长时间。

CREATE TABLE IF NOT EXISTS `pharma` (
  `ID` int(4) NOT NULL,
  `drug` varchar(90) DEFAULT NULL, //index
  `form` varchar(20) DEFAULT NULL,
  `price` decimal(7,2) DEFAULT NULL,
  `Company` varchar(54) DEFAULT NULL,
  `Pharmacology` varchar(96) DEFAULT NULL
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=92064 ;

SELECT *
FROM `pharma`
WHERE `drug` LIKE '%PANADOL%' ESCAPE '!'
AND  `drug` LIKE '%500%' ESCAPE '!'
AND  `drug` LIKE '%mg%' ESCAPE '!'
AND  `drug` LIKE '%fc%' ESCAPE '!'
AND  `drug` LIKE '%PANADOL%' ESCAPE '!'
AND  `drug` LIKE '%500%' ESCAPE '!'
AND  `drug` LIKE '%mg%' ESCAPE '!'
ORDER BY (CASE
            when drug LIKE 'PANADOL %' then 1
            when drug LIKE 'PANADOL%' then 2
            when drug LIKE '% PANADOL%'  then 3
            when drug LIKE '%PANADOL%'  then 4
            else 4
            end)
 LIMIT 15; //average excution time 1.7sec;

我尝试将表格转换为MYISAM以使用fulltext索引,但我无法对其进行调整以充当有效搜索。因为我的用户通常输入与数据库中的记录顺序不同的单词,所以我需要使用导致索引无用的前导%

1 个答案:

答案 0 :(得分:0)

MATCH (drug) AGAINST ('+PANADOL +500 +mg' IN BOOLEAN MODE)

然而,在将ft_min_word_len更改为2之后,您必须[重新]构建索引才能捕获" mg"。

使用" +"和" BOOLEAN",这些单词的顺序无关紧要。但是," 500mg"不会被抓住,所以你应该把它分成" 500毫克"插入时。

当桌子很大时,使用LIKE和%的速度非常慢。特别是因为你有多个LIKE。

一种折衷方法是使用FULLTEXT查找某些单词,然后使用LIKE确保它们正确传播。 FT将会很快并且提供的行数要少得多。例如:

SELECT ... FROM tbl
    WHERE MATCH(drug) AGAINST('+PANADOL' IN BOOLEAN MODE)
      AND ... LIKE ...
      AND ... LIKE ...
      ...
    ORDER BY ...;

此外,它可能值得预先形成上述查询,但它返回空,然后假设PANADOL丢失并对其余单词执行较慢的LIKE。这样,大多数查询都可以快速查询,同时惩罚那些无法正确拼写药物的人。