用子查询改进mysql查询左外连接

vaqhlq81  于 2021-06-23  发布在  Mysql
关注(0)|答案(1)|浏览(401)

我们正在维护内容的历史记录。我们要得到每个内容的更新条目,创建时间和更新时间应该是内容的第一个条目。查询包含多个selects和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'

任何帮助都将不胜感激。谢谢您。

t3psigkw

t3psigkw1#

只是部分评估和建议,因为您的查询似乎格式不正确
这个左连接似乎没有用

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

同一张table
join中子查询中的order by(无限制)无效,因为join ordered值或unordered值产生相同的结果
groupbycontentid很奇怪,因为没有聚合函数,groupbywithoutaggregation函数的用法是sql,在mysql的最新版本中是不允许的(deafult)如果您需要不同的值或者每个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

对于其余的列,您应该明确地选择您实际需要的列,并为其他列添加适当的聚合函数
另外,嵌套的子查询只是为了减少行数,对性能没有帮助。。。你也应该重新评估你的数据建模和设计。

相关问题