сложный SQL, который работает очень медленно, когда запрос имеет порядок по выражению - PullRequest
2 голосов
/ 22 апреля 2010

У меня следующий сложный запрос, который мне нужно использовать. Когда я запускаю его, это занимает от 30 до 40 секунд. Но если я уберу заказ по предложению, то для возврата результата потребуется 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 является первичным ключом, который тоже индексируется. Так что я не знаю, в чем проблема.

У меня также есть таблица разрешений для альбомов и альбомов, просто чтобы проверить, является ли медиа общедоступным или частным, если он личный, то проверьте, имеет ли пользователь разрешение или нет. Я думал, может быть, это является причиной проблемы. Что если я сделаю это в подзапросе, будет ли это работать лучше? Также может кто-нибудь помочь мне написать этот подзапрос, если это решение? Если ты не можешь помочь написать это, просто скажи мне. Я действительно схожу с ума от этой проблемы ..

РЕШЕНИЕ МОЖЕТ БЫТЬ

Да, я думаю, что подзапрос был бы лучшим решением для этого, потому что следующий запрос выполняется в 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   

1 Ответ

1 голос
/ 22 апреля 2010

Используйте 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 разных запроса и объединить их вместе, чтобы избежать внешнего объединения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...