0

我有三张桌子,我必须用类似的匹配来搜索它们。该查询运行超过 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 FOR THAT 列。

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

结果

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

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

4

4 回答 4

1

您可以考虑很多事情:

这里性能的主要杀手可能是regex_replace() ... like '%FOO%'. 鉴于您在列上应用函数,索引不会生效,留下几个全表扫描。更不用说正则表达式替换将是重量级的。为了优化,您可以

  1. 保留一个单独的列,该列存储“已清理”数据,您可以为其创建索引,并留下您的查询where pc_name_sanitized like '%FOO%'
  2. 我不确定它是否在 MySql 中可用,但是在很多 DMBS 中,有一个称为基于函数的索引的功能。您可以考虑使用它来索引正则表达式替换功能

但是即使经过上述更改,您会发现性能并不是很吸引人。在大多数情况下,在前面使用 like 和通配符可以避免使用索引。如果可能,尝试进行完全匹配,或者提供字符串的开头,例如where pc_name_sanitized like 'FOO%'

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

于 2013-08-27T07:16:51.443 回答
0

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

于 2013-08-27T06:57:21.657 回答
0

我要说的是不要过滤查询。无论您使用哪种语言进行编程,都可以执行此操作。无论环境如何,Regex_replace 都是一项繁重的操作,并且您在查询 10,000 条记录时多次执行此操作,并且谁知道还有多少条记录。

于 2013-08-27T07:00:05.753 回答
0

完全重写它。 UNION语句正在扼杀性能,而您LIKE在太多领域上做事。此外,您正在搜索一个临时表 ( SELECT field FROM (...subquery...)),因此没有任何索引,这真的很慢(每行都有 1/1 的机会进行全表扫描)。

于 2013-08-27T07:00:44.640 回答