我无法理解如何解决看似简单的排序结果问题。
我想比较有多少其他用户喜欢与ID为1的用户相同的水果,计算匹配最多的用户并按降序显示结果。
用户:
1 jack
2 john
3 jim
水果:
id, title
1 apple
2 banana
3 orange
4 pear
5 mango
关系:2个索引(user_id,fruit_id)和(fruit_id,user_id)
user_id, fruit_id
1 1
1 2
1 5
2 1
2 2
2 4
3 3
3 1
预期结果:(与杰克最喜欢的水果(user_id = 1)比较)
user_id, count
1 3
2 2
3 1
查询:
SELECT user_id, COUNT(*) AS count FROM relations
WHERE fruit_id IN (SELECT fruit_id FROM relations WHERE user_id=1)
GROUP BY user_id
HAVING count>=2
更多"优化"查询:
SELECT user_id, COUNT(*) AS count FROM relations r
WHERE EXISTS (SELECT 1 FROM relations WHERE user_id=1 and r.fruit_id=fruit_id)
GROUP BY user_id
HAVING count>=2
2是最小匹配数。 (未来需要)
解释
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY r index NULL uid 8 NULL 15 Using where; Using index
2 DEPENDENT SUBQUERY relations eq_ref xox,uid xox 8 r.relations,const 1 Using where; Using index
一切正常,直到我尝试使用ORDER BY count DESC
然后我看到:使用临时;使用filesort
我不想使用临时表或filesort。因为将来数据库应该处于高负荷状态。
我知道,这就是SQL的定义方式及其运作方式。但我无法弄清楚如何以其他方式做到这一点?没有临时表和filesort。
我需要先显示匹配次数最多的用户。
请帮帮我。
UPD: 我使用Walker Farrow的查询进行了一些测试(它仍然使用文件排)。
20,000 rows - avg 0.05 seconds
120,000 0.20 sec.
1,100,000 2.9 sec.
结果令人失望。
可以改变表结构,但是,通过这样的计数和排序 - 我不知道如何。
对于如何做到这一点有什么建议吗?
答案 0 :(得分:0)
执行此操作的最佳方法可能是创建子查询,然后在外部查询中按顺序排序,如下所示:
select *
from (
SELECT user_id, COUNT(*) AS count FROM relations r
WHERE EXISTS (SELECT 1 FROM relations WHERE user_id=1 and r.fruit_id=fruit_id)
GROUP BY user_id
HAVING count(*)>=2
) x
order by count desc
另外,我不知道您需要添加exists
的原因。你能说出以下几点:
select *
from (
SELECT user_id, COUNT(*) AS count FROM relations r
WHERE user_id=1
GROUP BY user_id
HAVING count(*)>=2
) x
order by count desc
我不确定,也许我错过了什么。 HOpe有帮助!