简体   繁体   English

MYSQL带有子查询的中等查询优化

[英]MYSQL medium query optimization with subqueries

I have this query that returns the following: 我有此查询返回以下内容:

  • Region name 地区名称
  • Region ID 地区编号
  • RANK (Position) of this Region, based on the total number of votes 根据投票总数,该区域的排名(位置)
  • Nb of distinct users from this region Nb来自该地区的不同用户
  • Nb of distinct photos from this region Nb来自该地区的不同照片

The query take about ~7.5s to complete... I'd like some advice to optimize my query. 该查询大约需要7.5秒才能完成...我想一些建议来优化查询。

            select
            WrappedQuery.*,
            regions.name as region_name,
            regions.id as region_id,
            count(distinct users.id) as nb_users,
            count(distinct photos.id) as nb_photos
            from (
                select
                  @rownum := @rownum +1 as rank,
                  prequery.region_id,
                  prequery.VoteCount
                from
                  ( select @rownum := 0 ) sqlvars,
                  ( select region_id, count(id) VoteCount
                      from votes
                      where theme_id = '{$currentTheme}'
                      group by region_id
                      order by count(id) desc ) prequery
              ) WrappedQuery, regions, users, photos
              WHERE regions.id = WrappedQuery.region_id
              AND users.region_id = WrappedQuery.region_id
              AND photos.region_id = WrappedQuery.region_id
              GROUP BY WrappedQuery.region_id
              ORDER BY WrappedQuery.rank ASC
              LIMIT 0, 1

Thanks a lot in advance. 非常感谢。

Your query has way too much overhead for what you want to achieve. 您的查询有太多的开销要实现。 I've rewritten it for you... 我替你改了

select 
/*you don't need that
@rownum := @rownum +1 as rank, 
*/
regions.name as region_name,
regions.id as region_id,
count(distinct users.id) as nb_users,
count(distinct photos.id) as nb_photos,
count(votes.id) as VoteCount
from votes
INNER JOIN regions ON votes.region_id = regions.id
INNER JOIN users ON users.region_id = regions.id
INNER JOIN photos ON photos.region_id = regions.id
/*you don't need that
, ( select @rownum := 0 ) sqlvars
*/
where theme_id = '{$currentTheme}'
group by regions.id
order by VoteCount DESC
LIMIT 1

I commented out the part with the rank, since you just want 1 row anyway. 我注释掉了具有等级的部分,因为无论如何您只想要1行。

If it still is too slow, you have to post the result of EXPLAIN SELECT .../*the query from above*/ , so we can see if an index is used. 如果仍然太慢,则必须发布EXPLAIN SELECT .../*the query from above*/的结果EXPLAIN SELECT .../*the query from above*/ ,以便我们可以查看是否使用了索引。 Also post the table creation scripts (with SHOW CREATE TABLE tableName ). 还发布表创建脚本(使用SHOW CREATE TABLE tableName )。 Either this, or you try to create missing indexes yourself. 要么这样做,要么尝试自己创建丢失的索引。

UPDATE: 更新:

Rewritten your query again, might be faster this way: 再次重写查询,这种方式可能会更快:

select
WrappedQuery.*,
regions.name as region_name,
regions.id as region_id,
count(distinct users.id) as nb_users,
count(distinct photos.id) as nb_photos
from (
       select region_id, count(id) VoteCount
          from votes
          where theme_id = '{$currentTheme}'
          group by region_id
          ORDER BY VoteCount DESC
          LIMIT 1
  ) WrappedQuery, regions, users, photos
  WHERE regions.id = WrappedQuery.region_id
  AND users.region_id = WrappedQuery.region_id
  AND photos.region_id = WrappedQuery.region_id
  GROUP BY WrappedQuery.region_id

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

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