请问如下SQL语句可以如何优化?

问题描述

现有如下SQL语句:

 SELECT `h1`.`oid`,`hr`.`uid`,`h1`.`bid`,`isself`,`tag`,h1.name as hname,
h1.add as hadd,
case when isself=1 then h2.name else h3.name end name ,
case when isself=1 then h2.add else h3.add end add
FROM `interv` `h1`
LEFT JOIN `relative` `hr` ON `h1`.`relative`=hr.relative and h1.oid=hr.oid
LEFT JOIN `self` `h2` ON `hr`.`uid`=`h2`.`uid`
LEFT JOIN `scrapy` `h3` ON `hr`.`uid`=`h3`.`uid`
WHERE  `h1`.`upon` = 1 
    and (case when isself=1 then h2.status else h3.status end)=2
    *and (case when isself=1 then h2.cid else h3.cid end)=2* 
order by h1.updatetime desc,
h1.createtime desc
limit 50 

问题出现的环境背景及自己尝试过哪些方法

现在我是给h1的updatetime,createtime建立一个联合索引,h2和h3的表中status和cid建立了联合索引,然后单独给status和cid也是建立了索引。但是现在执行效率较差。explain如下
图片描述

我将where条件中case when 那两行分别注释掉。发现是cid那一行严重拖慢了速度。注释掉之后,0.2s左右,加上就1s+

请问下如何处理可以优化一下这个效率

表结构如下:
图片描述
图片描述
图片描述
图片描述

阅读 2.5k
3 个回答

h1表没有使用到索引索引,所以type类型是index(全索引扫描)

给下表结构

h2和h3并无直接关系,建议拆开2条SQL,便于理解

SELECT *
FROM (
    (
        SELECT *
        FROM h1, hr, h2
        LIMIT 50
    )
    UNION
    (
        SELECT *
        FROM h1, hr, h3
        LIMIT 50
    )    
) a
ORDER BY a.time
LIMIT 50;

你说你self和scrapy合并成一张表,多添加个isself字段来区分,然后建立个uid,cid,status联合索引,不就没这么多事了。
实在要分开,建议self和scrapy表直接添加个uid,cid,status联合索引试看看。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏