MySQL查询 - 使用GROUP BY变得缓慢

时间:2018-01-15 20:31:17

标签: mysql performance mysqli indexing group-by

我花了4个小时谷歌搜索和尝试各种索引,mysqlyog,阅读,搜索等。我真的很感激一些帮助。当我添加GROUP BY时,查询从0.002秒更改为0.093秒。这是正常的吗?或者我可以更改索引和/或查询吗?非常感谢一些帮助。希望如果我得到答案,我可以利用这些知识向前推进......先谢谢。

表:

uniqueid    int(11) NO  PRI NULL    auto_increment  
ip  varchar(64) YES     NULL        
lang    varchar(16) YES MUL NULL        
timestamp   int(11) YES MUL NULL        
correct decimal(12,2)   YES     NULL        
user    varchar(32) YES     NULL        
timestart   int(11) YES     NULL        
timeend int(11) YES     NULL        
speaker varchar(64) YES     NULL        
postedAnswer    int(32) YES     NULL        
correctAnswerINT    int(32) YES     NULL

查询:

SELECT
  SQL_NO_CACHE 
  user,
  lang,
  COUNT(*) AS total,
  SUM(correct) AS correct,
  ROUND(SUM(correct) / COUNT(*) * 100) AS score,
  TIMESTAMP
FROM
  maths_score
WHERE TIMESTAMP > 1
  AND lang = 'es'
GROUP BY USER
ORDER BY (
    (SUM(correct) / COUNT(*) * 100) + SUM(correct)
  ) DESC
LIMIT 500

解释延伸:

    id  select_type  table        type    possible_keys              key             key_len  ref       rows  filtered  Extra                                                                
------  -----------  -----------  ------  -------------------------  --------------  -------  ------  ------  --------  ---------------------------------------------------------------------
     1  SIMPLE       maths_score  ref     scoretable,fulltablething  fulltablething  51       const    10631    100.00  Using index condition; Using where; Using temporary; Using filesort  

当前索引(我尝试了很多)

Keyname Type    Unique  Packed  Column  Cardinality Collation   Null    Comment

uniqueid    BTREE   Yes No  uniqueid    21262   A   No  

scoretable  BTREE   No  No  timestamp   21262   A   Yes 
    lang    21262   A   Yes

fulltablething  BTREE   No  No  lang    56  A   Yes 
    timestamp   21262   A   Yes
    user    21262   A   Yes

2 个答案:

答案 0 :(得分:1)

请使用SHOW CREATE TABLE;它比DESCRIBE更具描述性。

你有INDEX(lang, TIMESTAMP)吗? (Why.)它可能有助于两个版本的查询。

没有GROUP BY,你会得到一行,对吗?使用GROUP BY,您会收到很多行,对吗?猜猜是什么,需要更多时间来提供更多行。

此外,GROUP BY 可能涉及额外的排序。 ORDER BY涉及一种排序,但在一种情况下,只有一行要排序,因此更快。如果有一百万USERs,那么ORDER BY将需要排序一百万行,只能提供500行。

请为每个案例提供EXPLAIN SELECT ... - 您会看到我正在说的一些

答案 1 :(得分:0)

因此,您在没有GROUP BY的情况下运行查询,并在0.002秒内得到一个结果行。然后你添加了GROUP BY(显然是ORDER BY),最后得到了0.093秒的多个结果行。

为了产生这个结果,DBMS必须以某种方式按用户命令您的记录或为每个用户创建存储桶,以便获得每个用户的记录计数,总和等。当然,这比在表中运行,计算记录和无条件地总结一个值要花费更多的时间。最后,DBMS必须再次对这些结果进行排序。我跑的时间并不长,我并不感到惊讶。

此查询最合适的索引应为:

create index idx on maths_score (lang, timestamp, user, correct);

这是一个覆盖索引,从WHERE中的列开始,继续GROUP BY中的列,并以查询中使用的所有其他列结束。