需要确定哪个查询更快:
查询1
select xyz.user, count(*) as score
from xyz join
(select qid, min(time) as mintime
from xyz
group by qid
) q
on xyz.qid = q.qid and xyz.time = q.mintime
group by xyz.user;
QUERY2
select user,count(*)
from (select *
from (select *
from xyz
order by time ASC
) as temp1
group by temp1.qid
) As temp2
group by temp2.user
两者都返回用户对每个qid“第一”的次数。
DB:
CREATE TABLE xyz (
id INT PRIMARY KEY AUTO_INCREMENT,
user VARCHAR(20),
time INT,
qid INT
);
INSERT INTO xyz VALUES ( 1 , 'abc' , 15 , 1);
INSERT INTO xyz VALUES ( 2 , 'abc' , 6 , 1);
INSERT INTO xyz VALUES ( 3 , 'xyz' , 11 , 1);
INSERT INTO xyz VALUES ( 4 , 'abc' , 4 , 1);
INSERT INTO xyz VALUES ( 5 , 'xyz' , 13 , 2);
INSERT INTO xyz VALUES ( 6 , 'abc' , 11 ,2);
INSERT INTO xyz VALUES ( 7 , 'abc' , 9 , 3);
INSERT INTO xyz VALUES ( 8 , 'xyz' , 10 , 3);
INSERT INTO xyz VALUES ( 9 , 'xyz' , 2 , 3);
INSERT INTO xyz VALUES ( 10 , 'xyz' , 2 , 4);
编辑:建议更快地更换。
答案 0 :(得分:1)
您的第一个查询包含此子查询。
select qid, min(time) as mintime
from xyz
group by qid
(qid,time)
上的复合索引可以使效率非常高。 MySQL将使用所谓的loose index scan.来满足该查询。因此,如果我是你,我会使用您的第一个查询。
但你应该使用EXPLAIN
来确保我是对的。如果您的表格的行数是现在的100倍,您应该在将来的某个时间重新审视此问题。
答案 1 :(得分:1)
除此之外,您应该在用于搜索或比较的列上为表添加索引:
ALTER TABLE `xyz`
ADD INDEX (`qid`),
ADD INDEX (`time`);
然后将EXPLAIN
放在每个查询的前面,并根据您在手册中找到的the recommendations检查结果。仔细查看有关“加入类型”和“额外信息”的部分。
有或没有索引,请避免第二个查询。这是最糟糕的,无法改善。
我建议您使用另一种查询来产生相同的结果,甚至比第一种方法更快:
SELECT uif.user, COUNT(*) AS score
FROM xyz uif # "uif" from "user is first"
LEFT JOIN xyz sm # "sm" from "smaller time"
ON uif.qid = sm.qid AND sm.time < uif.time
WHERE sm.time IS NULL # keep only when there is no "smaller time"
GROUP BY uif.user
它将xyz
表(别名为uif
)与其自身连接(别名为sm
)。 uif
中的每一行都与sm
中具有相同qid
和更小时间(sm.time < uif.time
)的所有行配对。 LEFT JOIN
确保uif
中的所有行都会显示在已加入的集合中。如果uif
中的某一行没有来自sm
的一对(因为sm
中的行没有时间较短),sm
中的列将填充{ {1}}。
NULL
条件仅保留WHERE
中uif
中没有对的行(没有“较小的时间”);这意味着它只保留sm
中具有较小时间的行。
uif
和SELECT
条款会照顾您的原始目标(返回次数)。始终只在GROUP BY
条款中添加uid
的列(因为SELECT
的列全部都是sm
。
答案 2 :(得分:1)
这是关于速度的典型性能方案。至于任何此类情况,您必须进行测试和测量。
这本身就是一个非常棘手的任务,因为在第一次运行后,db引擎会缓存您的查询,并且后续执行会相当快。 在系统中测试和测量性能需要您考虑要正确完成许多变量。
另一方面:
我的估计是JOIN
的查询速度最快。现代sql数据库引擎擅长优化,JOIN
允许引擎自由优化查询。
答案 3 :(得分:0)
SELECT user, count(*) AS score
FROM xyz JOIN
(SELECT qid, min(time) AS mintime
FROM xyz
GROUP by qid
) q
ON qid = q.qid AND time = q.mintime
GROUP BY user;
我认为xyz.gid
和xyz.time
不是必需的