简体   繁体   English

MySQL GROUP BY优化

[英]MySQL GROUP BY optimisation

Can anyone tell me how I can speed up mysql group by clause? 谁能告诉我如何加快mysql group by子句? Ive read the documentation but it doesnt give any good examples. 我已经阅读了文档,但没有给出任何好的示例。

UPDATE SQL
SELECT
  post.topic_id,
  topic.topic_posts,
  topic.topic_title,
  topic.topic_poster_name,
  topic.topic_last_post_id,
  forum.forum_name AS group_name,
  `group`.slug AS child_slug,
  `parent`.slug AS parent_slug
FROM bb_posts post
LEFT JOIN bb_topics topic
  ON topic.topic_id = post.topic_id
LEFT JOIN bb_forums forum
  ON forum.forum_id = topic.forum_id
LEFT JOIN wp_bp_groups `group`
  ON topic.forum_id = `group`.id
LEFT JOIN wp_bp_groups `parent`
  ON `group`.parent_id = `parent`.id
WHERE (topic_title LIKE '%$search_terms%' || MATCH(post.post_text) AGAINST('$search_terms'))
   && topic_status = 0
GROUP BY topic_id
ORDER BY topic.topic_start_time DESC
LIMIT $offset,$num

The general best practice would be to make sure the field you are grouping on has an index. 一般的最佳做法是确保您要分组的字段具有索引。

The most general way to satisfy a GROUP BY clause is to scan the whole table and create a new temporary table where all rows from each group are consecutive, and then use this temporary table to discover groups and apply aggregate functions (if any). 满足GROUP BY子句的最通用方法是扫描整个表并创建一个新的临时表,其中每个组中的所有行都是连续的,然后使用该临时表发现组并应用聚合函数(如果有)。 In some cases, MySQL is able to do much better than that and to avoid creation of temporary tables by using index access. 在某些情况下,MySQL可以做得更好,并且可以避免使用索引访问来创建临时表。

  • Make sure that every foreign key has a corresponding index. 确保每个外键都有对应的索引。
  • Create covering indexes on the fields you retrieve 在您检索的字段上创建覆盖索引
  • Creating an index on the field you are sorting bij wouldn't hurt either. 在要排序的字段上创建索引也不会受到损害。

http://dev.mysql.com/doc/refman/5.0/en/group-by-optimization.html http://dev.mysql.com/doc/refman/5.0/en/group-by-optimization.html

Group by is fastest when you have an index on the column being grouped on, and: 当分组的列上有索引时,Group by最快,并且:

  • The query is over a single table. 查询是在单个表上。
  • The GROUP BY names only columns that form a leftmost prefix of the index and no other columns. GROUP BY仅命名构成索引最左前缀的列,而没有命名其他列。 (If, instead of GROUP BY, the query has a DISTINCT clause, all distinct attributes refer to columns that form a leftmost prefix of the index.) For example, if a table t1 has an index on (c1,c2,c3), loose index scan is applicable if the query has GROUP BY c1, c2,. (如果查询具有DISTINCT子句,而不是GROUP BY,则所有不同的属性都引用构成索引最左前缀的列。)例如,如果表t1在(c1,c2,c3)上具有索引,如果查询具有GROUP BY c1,c2,则松散索引扫描适用。 It is not applicable if the query has GROUP BY c2, c3 (the columns are not a leftmost prefix) or GROUP BY c1, c2, c4 (c4 is not in the index). 如果查询具有GROUP BY c2,c3(列不是最左边的前缀)或GROUP BY c1,c2,c4(c4不在索引中),则不适用。
  • The only aggregate functions used in the select list (if any) are MIN() and MAX(), and all of them refer to the same column. 选择列表中使用的唯一聚合函数(如果有)是MIN()和MAX(),它们全部引用同一列。 The column must be in the index and must follow the columns in the GROUP BY. 该列必须在索引中,并且必须在GROUP BY中。
  • Any other parts of the index than those from the GROUP BY referenced in the query must be constants (that is, they must be referenced in equalities with constants), except for the argument of MIN() or MAX() functions. 除MIN()或MAX()函数的参数外,查询中所引用的索引中除GROUP BY以外的任何其他部分都必须是常量(即,必须与常量相等地引用)。
  • For columns in the index, full column values must be indexed, not just a prefix. 对于索引中的列,必须索引完整的列值,而不仅是前缀。 For example, with c1 VARCHAR(20), INDEX (c1(10)), the index cannot be used for loose index scan. 例如,对于c1 VARCHAR(20),INDEX(c1(10)),索引不能用于松散索引扫描。

使where子句成为连接条件的一部分。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM