【问题标题】:PHP MySQL Match() Against() Fulltext search not working for some keywordsPHP MySQL Match() Against() 全文搜索不适用于某些关键字
【发布时间】:2016-11-24 13:47:44
【问题描述】:

我是 php 开发人员,但我遇到了 MySQL 全文搜索的问题。

这是我的查询

select distinct j.jobid,headline,company,country,state,city,location,
date_format(str_to_date(posted_dt, '%m-%d-%Y %H:%i:%s' ), '%M %d, %Y') posted_dt,joblinks 
from jobs j 
left join job_filters jf on jf.jobid = j.jobid 
left join job_emptype_map em on j.jobid = em.jobid 
left join job_sub_emptype_map sem on em.jobid = sem.jobid and em.emp_type = sem.emp_type 
where status=1 
And MATCH (headline,description,pri_skills,company) AGAINST ('java developer' IN natural language MODE) > 1 
And MATCH (location,country,state,city,zipcode,other_loc) AGAINST ('california, United States' WITH QUERY EXPANSION ) > 1 
order by str_to_date(posted_dt,'%m-%d-%Y %H:%i:%s') DESC limit 0,25

我通过上述查询得到了正确的结果。但它需要(显示第 0 - 24 行(共 25 行,查询耗时 50.6951 秒。)

当我更改关键字“ui developer”而不是“java developer”时,我得到 0 个结果

如果我用类似的功能检查关键字“ui developer”,那么我会得到结果。

我不明白为什么匹配功能仅适用于某些关键字,以及为什么当我的托管计划是云时它会花费太多时间。

【问题讨论】:

  • FULLTEXT 默认情况下不索引某些单词,包括 3 个字符和更短的每个字符,以及停用词列表。这在 MySQL 中是可配置的,尽管当您使用共享主机计划时通常无法配置。见stopwordstuning
  • 原来查询慢的原因,是因为可怕的order by子句。将日期存储为实际日期并添加索引。

标签: php mysql


【解决方案1】:

我现在在云服务器计划中,我已经用类似的功能更新了我的查询,现在我的查询是......

select distinct j.jobid,headline,company,country,state,city,location,date_format(str_to_date(posted_dt, '%m-%d-%Y %H:%i:%s' ), '%M %d, %Y') posted_dt,joblinks, (select count(distinct j.jobid) as jobcount from jobs j left join job_filters jf on jf.jobid = j.jobid left join job_emptype_map em on j.jobid = em.jobid left join job_sub_emptype_map sem on em.jobid = sem.jobid and em.emp_type = sem.emp_type where status = 1 and (concat(headline,' ',description,' ',pri_skills,' ',company) like '%java programer%' ) And ( country like '%United States%' ) ) jobcount from jobs j left join job_filters jf on jf.jobid = j.jobid left join job_emptype_map em on j.jobid = em.jobid left join job_sub_emptype_map sem on em.jobid = sem.jobid and em.emp_type = sem.emp_type where status=1 and (concat(headline,' ',description,' ',pri_skills,' ',company) like '%java programer%' )And ( country like '%United States%' ) order by str_to_date(posted_dt,'%m-%d-%Y %H:%i:%s') DESC limit 0,25   

我已经在上面的查询之间写了选择查询以进行分页,上面的查询得到了很好的结果但是花费了太多时间, 请注意:我的工作表有大约 50,000 多条记录

【讨论】:

  • order by str_to_date(posted_dt,'%m-%d-%Y %H:%i:%s') 正在杀死你。您将强制数据库执行此转换 50.000 次,然后它可以对其进行排序并从中获取 25 行的子集。要做到这一点,请将日期存储为实际数据并在该列上放置一个索引。然后排序会快得多,从中获取子集对您的数据库来说是小菜一碟。
  • 而且条件中带有%XYZ% 的 where 子句也很糟糕,就像在连续的字段中搜索一样。您基本上已经做了几乎所有事情来使您的查询尽可能慢。 FULLTEXT 使用实际索引。使用 like 搜索带有开头和结尾通配符的文本很糟糕。
  • 下次将您的问题分开。性能问题是一个不同的问题,仅靠这个答案在 cmets 中是无法解决的。
  • 非常感谢您提供宝贵的信息,我已根据您的指导对日期列进行了更改。但我无法理解条件中带有 %XYZ% 的 where 子句我必须做什么?请指导我。谢谢
  • 我已将多个列的值更新为单个列(我的新列名是 'search_job' ),用逗号(,)分隔,我正在从同一列(search_job)检索数据,所以对现在我正在使用like函数从单列中检索数据现在我的查询就像'%search_job%',但现在性能也很慢,请在这里查看reqsbook.com/all-keywords-search/united-states/…,请帮助我遇到麻烦。非常感谢
猜你喜欢
  • 1970-01-01
  • 2011-07-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-12
相关资源
最近更新 更多