我有以下需要使用的复杂查询。当我运行它时,需要30到40秒。但是如果我删除order by子句,则返回结果需要0.0317秒,这与30秒或40秒相比非常快。
select DISTINCT media.*
, username
from album as album
, album_permission as permission
, user as user, media as media
where ((media.album_id = album.album_id
and album.private = 'yes'
and album.album_id = permission.album_id
and (permission.email = '' or permission.user_id = '') )
or (media.album_id = album.album_id
and album.private = 'no' )
or media.album_id = '0' )
and media.user_id = user.user_id
and media.media_type = 'video'
order by media.id DESC
LIMIT 0,20
order by
上的ID是主键,也是索引。所以我不知道是什么问题。
我还有专辑和专辑权限表,只是为了检查媒体是公共还是私有,如果是私有的,那么检查用户是否拥有权限。我想也许这会导致问题。如果我在子查询中这样做会更好吗?也有人可以帮我写那个子查询,如果这是解决方案?如果你不能写出来,至少告诉我。我真的对这个问题发疯了。
解决方案可能
是的,我认为子查询是最好的解决方案,因为以下查询运行在0.0022秒。但我不确定专辑的验证是否准确,请检查。
select media.*, username
from media as media
, user as user
where media.user_id = user.user_id
and media.media_type = 'video'
and media.id in
(select media2.id
from media as media2
, album as album
, album_permission as permission
where ((media2.album_id = album.album_id
and album.private = 'yes'
and album.album_id = permission.album_id
and (permission.email = ''
or permission.user_id = ''))
or (media.album_id = album.album_id
and album.private = 'no' )
or media.album_id = '0' )
and media.album_id = media2.album_id )
order by media.id DESC
LIMIT 0,20
答案 0 :(得分:1)
如果没有ORDER BY子句,请使用EXPLAIN确定更快的原因:
http://dev.mysql.com/doc/refman/5.1/en/using-explain.html
我建议用ANSI连接语法重写查询。这可能有助于提高性能。像这样:
select DISTINCT media.*
, username
from album as album
inner join media as media on media.album_id = album.album_id
inner join user as user on media.user_id = user.user_id
left outer join album_permission as permission on album.album_id = permission.album_id
where ((album.private = 'yes'
and (permission.email = '' or permission.user_id = '') )
or album.private = 'no'
or media.album_id = '0' )
and media.media_type = 'video'
order by media.id DESC
LIMIT 0,20
您还可以将查询分成2个或3个不同的查询,并将它们联合起来以避免外部联接。