如何使用like搜索快速查询mysql

时间:2013-08-27 06:52:05

标签: mysql query-optimization

我有三张桌子,我必须用匹配搜索它们。该查询运行超过10,000条记录。它工作正常但需要4秒才能得出结果。我该怎么做才能提高速度并将其降低到1秒?

profile_category_table
----------------------
restaurant
sea food restaurant

profile_keywords_table
----------------------
rest
restroom
r.s.t

company_profile_table
---------------------
maha restaurants
indian restaurants

查询:

SELECT name
FROM (
        (SELECT PC_name AS name
         FROM profile_category_table
         WHERE PC_status=1
           AND PC_parentid!=0
           AND (regex_replace('[^a-zA-Z0-9\-]','',remove_specialCharacter(PC_name)) LIKE '%rest%')
         GROUP BY PC_name)
      UNION
        (SELECT PROFKEY_name AS name
         FROM profile_keywords_table
         WHERE PROFKEY_status=1
           AND (regex_replace('[^a-zA-Z0-9\-]','',remove_specialCharacter(PROFKEY_name)) LIKE '%rest%')
         GROUP BY PROFKEY_name)
      UNION
        (SELECT COM_name AS name
         FROM company_profile_table
         WHERE COM_status=1
           AND (regex_replace('[^a-zA-Z0-9\-]','',remove_specialCharacter(COM_name)) LIKE '%rest%')
         GROUP BY COM_name))a
ORDER BY IF(name LIKE '%rest%',1,0) DESC LIMIT 0, 2

我也为这些列添加了INDEX。

如果用户在文本框中搜索文本,则自动建议结果应该是...

结果

restaurant
sea food restaurant
maha restaurants
indian restaurants
rest
restroom
r.s.t

我使用regex_replace('[^ a-zA-Z0-9 - ]','',remove_specialCharacter(COM_name)从字段值中删除特殊字符,并使用该关键字删除数学..

4 个答案:

答案 0 :(得分:1)

你可以考虑很多事情:

这里表现的主要杀手可能是regex_replace() ... like '%FOO%'。鉴于您正在对列应用函数,索引将不会生效,从而使您进行多次全表扫描。更不用说正则表达式替换将是重量级。为了优化,您可以

  1. 保留一个单独的列,该列存储您为其创建索引的“已清理”数据,并将查询保留为where pc_name_sanitized like '%FOO%'
  2. 我不确定它是否在MySql中可用,但在很多DMBS中,有一个称为基于函数的索引的功能。您可以考虑使用它来索引正则表达式替换函数
  3. 然而即使经过上述变化,你会发现性能不是很吸引人。在大多数情况下,使用前面的通配符就像避免使用索引一样。如果可能,尝试进行完全匹配,或者提供字符串的开头,例如where pc_name_sanitized like 'FOO%'

    正如其他提到的用户所提到的,使用UNION也是一种性能杀手。如果可能,请尝试使用UNION ALL

答案 1 :(得分:0)

由于您在所有查询之间使用union,因此您可以删除所有查询中的group by选项,并且只选择其中包含“rest”的列。所以删除order by子句中的函数"IF(name LIKE '%rest%',1,0)"

答案 2 :(得分:0)

我要说不要过滤查询。无论你编写什么语言,都可以这样做.Regex_replace是一个繁重的操作,无论环境如何,你在10,000条记录的查询中多次这样做,并且知道有多少联合。

答案 3 :(得分:0)

完全重写它。 UNION语句会破坏性能,而您在太多字段上执行LIKE。 此外,您正在搜索临时表(SELECT field FROM (...subquery...)),因此没有任何索引,这非常慢(每行有1/1的机会通过全表扫描)。