更快的搜索方式在多个数据库中

时间:2018-04-03 11:57:06

标签: php python mysql full-text-search query-performance

我正在开发大型电子商务购物网站。我有大约40个数据库。我想创建一个搜索页面,在所有数据库中按标题搜索后显示18个结果。

(SELECT id_no,offers,image,title,mrp,store from db1.table1 WHERE MATCH(title) AGAINST('$searchkey') AND title like '%$searchkey%')
 UNION ALL (SELECT id_no,offers,image,title,mrp,store from db3.table3 WHERE MATCH(title) AGAINST('$searchkey') AND title like '%$searchkey%')
 UNION ALL (SELECT id_no,offers,image,title,mrp,store from db2.table2 WHERE MATCH(title) AGAINST('$searchkey') AND title like '%$searchkey%') 
LIMIT 18

目前我正在使用上述查询工作正常4个或更多字符关键字搜索,如笔记本电脑诺基亚等,但过程需要10-15秒但查询关键字少于3个字符需要30-40秒或我最终500内部服务器错误。是否有任何优化的方式在多个数据库中进行搜索。 我生成了两个索引主要和全文索引,标题为

  

目前我的搜索页面是在php中,我准备用python或其他代码编写代码   其他语言如果我的速度很快

3 个答案:

答案 0 :(得分:0)

您可以使用sphixmachine:http://sphinxsearch.com/。这是强大的数据库搜索。恕我直言狮身人面像这个最好的决定  在您的网站上搜索。

答案 1 :(得分:0)

未配置FULLTEXT(默认情况下),用于搜索长度小于三个字符的单词。您可以通过设置...min_token_size参数来配置处理较短的单词。读这个。 https://dev.mysql.com/doc/refman/5.7/en/fulltext-fine-tuning.html只有控制MySQL服务器才能执行此操作。它在共享主机上无法实现。试试这个。

FULLTEXT旨在产生比假阴性匹配更多的假阳性匹配。它通常对填充下拉菜单最有用,例如浏览器位置字段下的选项列表。也就是说,它需要一些人工交互才能选择正确的记录。期望FULLTEXT能够做出绝对正确的搜索可能是一个坏主意。

如果您想要任何合理的表现,则根本无法使用AND column LIKE '%whatever%'。你必须摆脱它。当搜索项是一个或两个字母时,您可能能够重写python程序以执行不同的操作,从而避免许多(但不是全部)LIKE '%a%'LIKE '%ab%'操作。如果您选择此路线,请在title列上创建普通索引。 无论您做什么,都不要在单个查询中结合FULLTEXT和LIKE搜索

如果这是我的项目,我考虑使用一个包含这样的列的特殊表来保存每个表格每行中title列的所有简短字词。

id_pk INT autoincrement
id_no INT
word  VARCHAR(3) 

然后你可以使用这样的查询来查找短词

  SELECT a.id_no,offers,image,title,mrp,store 
    FROM db1.table1 a
    JOIN db1.table1_shortwords s ON a.id_no = s.id_no
   WHERE s.word = '$searchkey'

为此,您必须预先处理其他表的title列以填充短字表,并在word列上添加索引。这将很快,但它需要一个专用程序来进行预处理。

使用UNION ALL操作搜索多个表是一个性能问题。通过重新设计架构,您将能够显着提高性能,因此您只需要搜索一个表。

必须在不同服务器计算机上搜索数据库是一个性能问题。您可以安装python程序以并行搜索它们:也就是说,以某种方式使用单独的任务来搜索每个任务,然后聚合结果。每个单独的搜索任务都需要自己与数据库的连接,因此这不是一个便宜或简单的解决方案。

如果这个系统面向公共网络,你必须迟早重新设计它,因为它永远不会表现得像现在这样。 (很抱歉成为坏消息的承担者。)许多系统设计人员喜欢避免在系统变得巨大之后重新设计系统。所以,如果我是你,我会完成重新设计。

答案 2 :(得分:0)

如果你专注于搜索,那么弯曲架构以方便搜索而不是相反。

  • 收集要在单个表格中搜索的所有字符串。虽然40个表中的UNION确实起作用,但它的收集速度将是收集字符串的速度的40倍。
  • 当单词足够长时使用FULLTEXT,否则使用其他技巧。 (这解决了你的3-char问题;另请参阅答案讨论innodb_ft_min_token_size。你 使用InnoDB,对吗?)
  • 使用+和布尔模式表示必填字词:MATCH(col) AGAINST("+term" IN BOOLEAN MODE)
  • 除非有充分理由,否则请勿添加LIKE条款。