Улучшить MySql-запрос для левых внешних объединений с помощью подзапроса - PullRequest
0 голосов
/ 27 апреля 2018

Мы поддерживаем историю контента. Мы хотим получить обновленную запись каждого контента, при этом время создания и обновления должно относиться к первой записи контента. Запрос содержит несколько предложений select и where с таким количеством левых объединений. Набор данных очень большой, поэтому выполнение запроса занимает более 60 секунд. Пожалуйста, помогите улучшить то же самое. Запрос:

select * from (select * from (

    SELECT c.*, initCMS.initcreatetime, initCMS.initupdatetime, user.name as partnerName, r.name as rightsName, r1.name as copyRightsName, a.name as agelimitName, ct.type as contenttypename, cat.name as categoryname, lang.name as languagename FROM ContentCMS c 

        left join ContentCategoryType ct on ct.id = c.contentType 
        left join User user on c.contentPartnerId = user.id 
        left join Category cat on cat.id = c.categoryId 
        left join Language lang on lang.id = c.languageCode 
        left join CopyRights r on c.rights = r.id 
        left join CopyRights r1 on c.copyrights = r1.id 
        left join Age a on c.ageLimit = a.id 
        left outer join (

            SELECT contentId, createTime as initcreatetime, updateTime as initupdatetime from ContentCMS cms where cms.deleted='0'

        ) as initCMS on initCMS.contentId = c.contentId WHERE c.deleted='0' order by c.id  DESC

) as temp group by contentId) as c where c.editedBy='0'

Любая помощь будет принята с благодарностью. Спасибо.

1 Ответ

0 голосов
/ 27 апреля 2018

Просто частичное подтверждение и предложение, потому что ваш запрос кажется неправильно сформированным

Это левое соединение кажется бесполезным

    FROM ContentCMS c 
    ......
    left join (
        SELECT contentId
            , createTime as initcreatetime
            , updateTime as initupdatetime 
        from ContentCMS cms 
        where cms.deleted='0'
    ) as initCMS on initCMS.contentId = c.contentId 

тот же стол

порядок по (без ограничения) в подзапросе в соединении является бесполезным, поскольку упорядоченные значения или неупорядоченное значение объединения дают одинаковый результат

группировка по contentId странная, потому что нет функции агрегации, а иск группы без функции агрегирования устарел: sql и в самой последней версии для MySQL не допускается (по умолчанию), если вам нужно отдельное значение или просто строки для каждого contentId, вы должны использовать отличное или получить значение не случайным образом (использование group by без функции агрегирования случайное значение для неагрегированного столбца.

для частичного вычисления ваш запрос должен быть изменен на

SELECT c.*
          , c.initcreatetime
          , c.initupdatetime
          , user.name as partnerName
          , r.name as rightsName
          , r1.name as copyRightsName
          , a.name as agelimitName
          , ct.type as contenttypename
          , cat.name as categoryname
          , lang.name as languagename 
      FROM ContentCMS c 
      left join ContentCategoryType ct on ct.id = c.contentType 
      left join User user on c.contentPartnerId = user.id 
      left join Category cat on cat.id = c.categoryId 
      left join Language lang on lang.id = c.languageCode 
      left join CopyRights r on c.rights = r.id 
      left join CopyRights r1 on c.copyrights = r1.id 
      WHERE c.deleted='0' 
) as temp 

для остальных вы должны явно выбрать столбец, который вам необходим, добавить правильную функцию агрегирования для остальных

Кроме того, вложенный подзапрос только из-за ненадлежащего сокращения строк не влияет на производительность ... вам также следует повторно оценить моделирование и проектирование данных.

...