查询优化顺序依据

时间:2013-09-22 09:51:48

标签: mysql sql sorting indexing

我有两张桌子

  1. LangArticles | columns:id(INT),de(VARCHAR),en(VARCHAR),count_links(INT)
  2. WikiLinks | columns:article_id,link_id,nr_in_article(all integer)
  3. 文章的名称位于de(德语)和en(英语)列中。 LangArticles表中的id与ids article_id和link_id相同。

    我现在想要获取链接到另一篇文章的所有文章名称。所以我想要所有链接到'abc'的文章。 'abc'的id ='1'

    所以我的正常查询(没有订单)看起来像:

     select distinct(LA.de),W.nr_in_article,LA.count_links from
     LangArticles as LA inner join WikiLinks as W on W.article_id = LA.id
     where W.link_id in ("1") 
    

    这可能需要0.001秒,并给我100000个结果。其实我想要最好的5次点击。 在这种情况下,最好的方法是最相关的。我想这样排序: 在文章开头(nr_in_article)链接到'abc'并且本身有很多链接(count_links)的文章应该排名很高。

    我正在使用

    order by (1-(W.nr_in_article/LA.count_links)) desc 
    

    为此。

    问题在于我不确定如何优化此订单。

    mysql中的Explain说他必须使用临时文件和filesort,并且不能使用按键排序的索引。为了测试,我尝试了W.nr_in_article的“简单”订单,因此使用一个密钥进行正常订购。

    我的索引是您的信息:

    LangArticles中的

    :id(主要),de(唯一),en(唯一),count_links(索引)

    WikiLinks中的

    :article_id(索引),link_id(索引),nr_in_article(索引)

    但我尝试了这两个多重指示link_id,nr_in_article& article_id,nr_in_article以及。

    订单查询花了大约5.5秒。 :(

    我想我知道为什么MySql必须在这里使用临时文件和filesort,因为必须在一个索引(link_id)中找到所有100,000个条目,然后必须对它进行排序并且在临时文件中它不能使用指数。

    但有什么方法可以让它更快? 实际上我只想要最好的5次点击,所以没有必要对所有内容进行排序。我不确定是不是......喜欢坏排序(冒泡排序)比Quicksort排序孔临时表更快。

1 个答案:

答案 0 :(得分:0)

由于您只需要前五名,我认为您可以将其拆分为两个查询,这些查询应该会导致较少的结果。

首先像Sam指出的那样,

order by (W.nr_in_article/LA.count_links) asc

应该等同于你的

order by (1-(W.nr_in_article/LA.count_links)) desc 

除非我在这里忽略了一些角落的情况。

此外,任何地方

W.nr_in_article > LA.count_links

将在TOP 5中,除非结果为空,所以我会尝试查询

 select distinct(LA.de),W.nr_in_article,LA.count_links
 from LangArticles as LA 
 inner join WikiLinks_2 as W on W.article_id = LA.id
 and W.nr_in_article > LA.count_links
 where W.link_id in ("1")
 order by W.nr_in_article/La.count_links
 limit 5

仅当返回少于5个结果时,您必须使用更改的where条件再次执行查询。

然而,这不会使运行时间降低数量级,但应该有所帮助。如果你需要更多的性能我没有看到任何其他方式,而不是物化视图,我认为它不是在mysql中可用,但可以使用触发器进行模拟。