我有两张 table
- Lang文章 |列:id (INT)、de (VARCHAR)、en (VARCHAR)、count_links(INT)
- 维基链接 |列:article_id、link_id、nr_in_article(均为整数)
文章的名称位于 de(德语)和 en(英语)列中。 LangArticles 表中的 id 与 idarticle_id 和 link_id 相同。
我现在想要获取链接到另一篇文章的所有文章名称。所以我想要链接到“abc”的所有文章。 'abc' 的 id = '1'
所以我的正常查询(没有 order by)看起来像:
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首。 在这种情况下,最佳意味着最相关的。我想这样排序: 在文章开头链接到“abc”的文章 (nr_in_article) 以及本身具有大量链接 (count_links) 的文章应该具有较高的排名。
我正在使用
order by (1-(W.nr_in_article/LA.count_links)) desc
为此。
问题是我不知道如何优化这个顺序。
mysql中的Explain说他必须使用临时文件和文件排序,并且不能使用按键排序的索引。为了进行测试,我尝试了 W.nr_in_article 的“简单”订单,因此是一键正常订单。
供您引用,我的索引是:
在 LangArticles 中:id(主要)、de(唯一)、en(唯一)、count_links(索引)
在维基链接中:article_id(index),link_id(index),nr_in_article(index)
但我也尝试了这两个多索引 link_id,nr_in_article 和article_id,nr_in_article。
使用 order by 进行查询大约需要 5.5 秒。 :(
我想我知道为什么MySql必须在这里使用临时文件和文件排序,因为必须使用一个索引(link_id)找到所有100,000个条目,然后必须对它进行排序,并且在临时文件中它不能使用指数。
但是有什么办法可以让它更快吗? 实际上我只想要最好的 5 个点击,所以不需要对所有内容进行排序。我不确定是否某事。就像坏排序(冒泡排序)会比对洞临时表进行排序的快速排序更快。
最佳答案
由于您只需要前 5 个,我认为您可以将其拆分为两个查询,这会导致更少的结果。
首先,正如 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
除非结果为空,否则将进入前 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 条件再次进一步执行查询。
然而,这不会使运行时间降低几个数量级,但应该会有所帮助。如果您需要更高的性能,除了物化 View 之外,我没有看到任何其他方法,我认为物化 View 在 mysql 中不可用,但可以使用触发器进行模拟。
关于mysql - 查询优化排序依据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18942515/