我有两张桌子
文章的名称位于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排序孔临时表更快。
答案 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中可用,但可以使用触发器进行模拟。