使用groupby和orderby的MySQL查询中的性能问题

使用groupby和orderby的MySQL查询中的性能问题,mysql,query-optimization,query-performance,slowdown,Mysql,Query Optimization,Query Performance,Slowdown,1) 使用的第一个查询。。。大约花了23秒 select a.id from mza_movie_upload a,mza_movie_statics b where a.status=1 and b.download=1 and a.id=b.rid group by b.rid order by sum(b.download) desc 目前我修改了查询..大约需要9秒 select a.id from mza_movie_upload a INNER JOIN mza_movie_

1) 使用的第一个查询。。。大约花了23秒

select a.id from mza_movie_upload a,mza_movie_statics b 
where a.status=1 and b.download=1 and a.id=b.rid 
group by b.rid order by sum(b.download) desc
目前我修改了查询..大约需要9秒

select a.id from mza_movie_upload a 
INNER JOIN mza_movie_statics b 
ON a.id=b.rid WHERE a.status=1 and b.download=1 
group by b.rid order by sum(b.download) desc

explain select a.id from mza_movie_upload a  INNER JOIN mza_movie_statics b  ON     a.id=b.rid WHERE a.status=1 and b.download=1  group by b.rid order by sum(b.download) desc;
+----+-------------+-------+--------+---------------+---------+---------+----------------------+---------+----------------------------------------------+ |id |选择|类型|类型|可能的|键|键|列|参考|行|额外| +----+-------------+-------+--------+---------------+---------+---------+----------------------+---------+----------------------------------------------+ |1 | SIMPLE | b | ALL | NULL | NULL | NULL | NULL | 1603089 |使用where;使用临时设备;使用文件排序| |1 | SIMPLE | a | eq | ref | PRIMARY | PRIMARY | 4 | mmdfurni | u dev11.b.rid | 1 |使用where| +----+-------------+-------+--------+---------------+---------+---------+----------------------+---------+----------------------------------------------+ 一组2行(0.03秒) 我不确定要做什么表演?我希望这个查询能够快速进行。。 我试图索引rid和id,这仍然使查询变得更糟

这是表格的详细信息

mza_电影上传

+---------------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +---------------+--------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | userid | varchar(200) | NO | | NULL | | | email | varchar(200) | NO | | NULL | | | up_date | datetime | NO | | NULL | | | file_size | varchar(200) | NO | | NULL | | | temp_filename | varchar(200) | NO | | NULL | | | fileneame | varchar(200) | NO | MUL | NULL | | | filepath | varchar(255) | NO | | NULL | | | status | varchar(20) | NO | | NULL | | | ip | varchar(200) | NO | | NULL | | | category | varchar(200) | NO | | NULL | | | mcode | bigint(20) | NO | | NULL | | | movie_name | varchar(200) | NO | | NULL | | +---------------+--------------+------+-----+---------+----------------+ 13 rows in set (0.00 sec) +---------------+--------------+------+-----+---------+----------------+ |字段|类型|空|键|默认|额外| +---------------+--------------+------+-----+---------+----------------+ |id | int(11)| NO | PRI | NULL |自动增量| |userid | varchar(200)| NO | | NULL || |电子邮件| varchar(200)|否| |空|| |最新|日期时间|否|空|| |文件大小| varchar(200)|否|空|| |临时文件名| varchar(200)|否|空|| |fileneame | varchar(200)| NO | MUL | NULL || |filepath | varchar(255)| NO | | NULL || |状态| varchar(20)|否| |空|| |ip | varchar(200)| NO | | NULL || |类别| varchar(200)| NO | | NULL || |mcode | bigint(20)| NO | | NULL || |电影名称|瓦尔查尔(200)|否| |空|| +---------------+--------------+------+-----+---------+----------------+ 一组13行(0.00秒) 电影静力学

+-----------+---------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-----------+---------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | rid | int(11) | NO | | NULL | | | uid | int(11) | NO | | NULL | | | save | int(11) | NO | | NULL | | | download | int(11) | NO | | NULL | | | enterdate | date | NO | | NULL | | +-----------+---------+------+-----+---------+----------------+ 6 rows in set (0.00 sec) +-----------+---------+------+-----+---------+----------------+ |字段|类型|空|键|默认|额外| +-----------+---------+------+-----+---------+----------------+ |id | int(11)| NO | PRI | NULL |自动增量| |rid | int(11)| NO | | NULL || |uid | int(11)| NO | | NULL || |保存| int(11)| NO | | NULL || |下载| int(11)| NO | | NULL || |输入日期|日期|否| |空|| +-----------+---------+------+-----+---------+----------------+ 一组6行(0.00秒)
如果希望进一步提高性能,我建议对a.status和/或b.download应用索引。请记住,在插入/更新/删除记录方面,创建额外索引确实会带来额外的开销——在这种情况下,似乎有必要这样做

此外,在向这些表(可能是在您的生产环境中)添加新索引之前,请记住mysql将创建表的临时副本,对于具有大量记录(>100万)的表,这可能需要一段时间。(因此我建议在类似大小的桌子上进行本地测试)


最后,我注意到在您的查询中,where子句中有:a.status=1,但是status列是一个varchar。为了避免在两种不同的数据类型之间进行转换(这会减慢查询执行时间),并可能破坏未来的索引,我建议将其更改为:a.status='1'(注意引号)

尝试将查询重写为:

SELECT b.rid 
FROM mza_movie_upload a 
INNER JOIN mza_movie_statics b 
ON a.id=b.rid 
WHERE a.status= '1'  and b.download= '1'  
-- group by b.rid order by sum(b.download) desc;
GROUP BY b.rid ORDER BY count(*) DESC;
在该查询中,
SELECT a.id
替换为
SELECT b.rid
,由于
JOIN。。。在a.id=b.rid
谓词上,但使MySql的计划略好一些

正如@Dennis Leon sugested所说,
a.status='1'和b.download='1'
与字符串而不是数字进行比较。

还可以尝试用
order by count(*)desc替换
order by sum(b.download)desc
——因为查询只检索b.download='1'的行,所以
sum(b.download)
相当于
count(*)
-此更改允许在
SUM(..)
中将字符串转换为数字时节省数百毫秒。

最后创建两个索引:

create index bbbb on mza_movie_statics( download, rid );
create index aaaaa on mza_movie_upload( status );

在进行上述更改后,请尝试查询速度。

如果您有覆盖索引,您的查询可以得到更好的优化。那就是。。。索引中有与您要查找的内容(包括条件)关联的列。这样,引擎就不必访问原始数据来实际检查各自的状态和下载部件

因此,在mza_movie_上传上有一个索引(id、状态) 在mza_movie_上,静态有一个索引(rid,下载)

接下来,groupby将在驱动查询的索引上工作得最好,因为a.id=b.rid,但是a.id可以是驱动索引,所以让它成为groupby值

select
      mu.id
   from
      mza_movie_upload mu
         JOIN mza_movie_statics ms
            on mu.id = ms.rid
           AND ms.download > 0
   group by
      b.rid
   order by
      sum( b.download ) DESC
现在,请对下载内容发表评论。它似乎是一个数字,所以您可能不想显式地与“1”进行比较,因为该列似乎是某个内容下载次数的计数器。你要找的是下载次数最多的东西。如果该值始终为1,则
select
      mu.id
   from
      mza_movie_upload mu
         JOIN mza_movie_statics ms
            on mu.id = ms.rid
           AND ms.download > 0
   group by
      b.rid
   order by
      sum( b.download ) DESC