Tbl_responses
已
有5,000条记录。 “zac1987”发布了800条回复。 “zac1987”发布的800条回复中有30条差异msgid
。
SELECT DISTINCT msgid
FROM Tbl_responses
WHERE username = 'zac1987';
目前Explain SQL显示有800行受影响。如何优化查询,以便只有30行?我认为必须有一个解决方案来避免循环/过滤800条记录...就像用我在博客上显示的JOIN子句问题替换WHERE子句... ye5.blogspot.com/2011/07/optimize-faster-mysql-query-speed.html我正在寻找一些专家来避免循环800条记录的解决方案。
我的另一个问题 - 为什么这个页面http://forge.mysql.com/wiki/Top10SQLPerformanceTips说“当你拥有或可以使用GROUP BY时不要使用DISTINCT”因为它会减慢查询速度?但我已经测试过,结果没有减速,为什么?
答案 0 :(得分:2)
正如您所说,尝试重写查询以使用GROUP BY
子句:
SELECT msgid
FROM Tbl_responses
WHERE username = 'zac1987' GROUP BY msgid;
看看性能上的差异
答案 1 :(得分:1)
检查覆盖索引是否会在您的情况下表现更好。 http://ronaldbradford.com/blog/tag/covering-index/
答案 2 :(得分:1)
这两个查询是等价的:
SELECT DISTINCT msgid
FROM Tbl_responses
WHERE username = 'zac1987' ;
和
SELECT msgid
FROM Tbl_responses
WHERE username = 'zac1987'
GROUP BY msgid ;
我建议你在(username, msgid)
上制作复合索引。这将有助于任一版本的查询。
但最好是制作一个包含10K(甚至100k或1M)行的测试表并尝试速度和执行计划,首先使用(username)
上的简单索引,然后使用复合索引(username, msgid)
。
差异将显示在执行计划的Extra
列中,对于第一个带有简单索引的案例,它将显示 “使用where,using temporary” ,在第二种情况下,使用复合索引,它将显示 “使用位置,使用索引”
正如都铎指出的那样,担心5000记录的速度是过早的优化。当你有500K记录或者你看到性能下降时,你应该开始担心。
注意:这两个查询是 NOT 等效的,因此您不能总是通过将字段移动到GROUP BY来删除DINSTINT子句并期望得到相同的结果:
SELECT DISTINCT msgid, response
FROM Tbl_responses
WHERE username = 'zac1987' ;
和
SELECT msgid, response
FROM Tbl_responses
WHERE username = 'zac1987'
GROUP BY msgid ;
答案 3 :(得分:0)
放置一些条件,如WHERE username ='zac1987'AND id ='XYZ' 因为根据您的要求,不可能使用distinct和group过滤行。