2010-04-22 48 views
2

我有以下复杂的查询,我需要使用它。当我运行它时,需要30到40秒。但是,如果我一条一条地删除订单,需要0.0317秒,返回的结果,这是真快,比较30秒或40当查询按子句排序时运行速度非常慢的复杂sql

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是太索引的主键。所以我不知道是什么问题。

我也有相册和相册权限表,只是为了检查媒体是公共还是私人,如果是私人的,那么检查用户是否有权限。我想也许这是造成这个问题。如果我在子查询中这样做了,会更好吗?如果这是解决方案,也可以有人帮我写这个子查询吗?如果你不能写出来,至少告诉我。我真的要疯了这个问题..

SOLUTION MAYBE

是的,我觉得子查询将是这个最佳的解决方案,因为下面的查询在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

非常好Q.我很感兴趣,如果有人能想到这件事...... – TheCodeArtist 2010-04-22 06:44:43

+2

“请检查” - 你需要自己检查一下。测试两个查询。他们返回相同的结果吗? – APC 2010-04-22 06:54:08

+0

我无法检查对查询的验证,他们都返回相同的结果,但我也需要检查私人相册,哪些数据不是可用的..但无论如何,我会稍后添加它们,并检查..但是什么和为什么要这样做?我的意思是子查询确实比第一个查询更快。我测试了它们两个,结果是一样的。 – Basit 2010-04-22 07:37:22

回答

1

使用EXPLAIN来确定它为什么没有ORDER更快BY子句:

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个不同的查询,并将它们联合在一起以避免外部联接。

+0

你能告诉我为什么你推荐这个查询,而不是子查询。因为你的查询花费0.0897秒,子查询花费0.0016秒或0.0018秒加载。 – Basit 2010-04-23 05:28:29

+0

我个人认为子查询会更快,因为您不再需要DISTINCT。由于您没有使用IN子句从相册返回任何数据,因此通常会更快。但是,如果至少使用子查询版本,请更改为显式连接,它们更适合维护,而FAR不太可能意外地给出不正确的结果)使用隐式连接没有任何好处,因此没有任何理由使用语法20年前取代。 – HLGEM 2012-03-12 17:42:43

+0

@HLGEM你可以请示例使用显式连接..与此查询的例子 – Basit 2012-04-15 21:46:17