基于一个开源的维基系统(HDWIKI)做微信公众号开发,需要从维基里检索词条名和同义词,结果发现词条名和同义词存在数据库中的两个表里(结构没法改了)。
表1为wiki_doc,其中有一个字段title,内容为词条的标题;
表2为wiki_synonym,其中有一个字段desttitle,和表1的title字段对应,另一个字段srctitle是词条的同义词;
表1的一个title,在表2中可能会有多个对应项。现在在进行查询的时候,试图同时模糊搜索标题(wiki_doc.title)和同义词(wiki_synonym.srctitle),于是写了如下的语句:
select * from wiki_doc where (title like '%关键词%') OR (title in (select desttitle from wiki_synonym where srctitle like '%关键词%')) limit 10
结果无误,但效率很低(执行一次查询要4.53秒左右)听说exists比in快,换了一下,结果查询要4.57秒:
select * from wiki_doc where (title like '%塔亭路%') OR (exists (select desttitle from wiki_synonym where (srctitle like '%塔亭路%') and (desttitle = wiki_doc.title))) limit 10改成JOIN,更慢了(4.63秒):
SELECT * FROM wiki_doc LEFT JOIN wiki_synonym ON ( wiki_doc.title = wiki_synonym.desttitle ) WHERE ((wiki_doc.title LIKE '%塔亭路%')OR (wiki_synonym.srctitle LIKE '%塔亭路%')) limit 10无计可施了请问各位有没有什么好办法能优化这个查询效率的 

解决方案 »

  1.   

    1:用like时最好不要写%XX%,应该写XX%,这样才能走上索引.
    2:如果查询慢,你可以检查下是否查询走上了索引,
    3:你可以建立索引这三个(wiki_doc.title , wiki_synonym.desttitle wiki_synonym.srctitle )
    试下
      

  2.   

    * % or in 子查询,几乎所有破坏索引的都用了...
    给title,desttitle,wiki_synonym加索引
    然后用以下语句试试SELECT wiki_doc.* FROM wiki_doc WHERE title LIKE '%关键词%' UNION 
    SELECT wiki_doc.* FROM wiki_doc LEFT JOIN wiki_synonym ON wiki_doc.title=wiki_synonym.desttitle WHERE wiki_synonym.srctitle LIKE '%关键词%' GROUP BY wiki_doc.title估计也提高不了多少,关键还是你关键词前的%
    索引就像查字典,如果要查第一个字是“人”的词语就很快,如果要查的词中的“人”可能在任何位置的话那你就得翻遍整本字典了
    要想办法从需求设计上尽量避免这种查询方法
      

  3.   

    对了漏掉了limitSELECT wiki_doc.* FROM wiki_doc WHERE title LIKE '%关键词%' UNION 
    SELECT wiki_doc.* FROM wiki_doc LEFT JOIN wiki_synonym ON wiki_doc.title=wiki_synonym.desttitle WHERE wiki_synonym.srctitle LIKE '%关键词%' GROUP BY wiki_doc.title
    limit 10有了limit会好一些
      

  4.   

    left join替代in这样使用:select a.* from a left join b on a.id = b.id where b.id is not null,这样可以过滤一些不匹配的项