2017-10-06 187 views
1
SELECT PROJECTKEY, CONCAT(FIRSTNAME,' ',LASTNAME) as USRCREATED, 
           CONCAT('/userImages/',md.USERKEY,'/',md.IMAGE) as USRCREATED_PROFILE_IMG,mm.DTCREATED 
           FROM kbedumoment mm 
           left join users md on mm.USRCREATED=md.USERKEY 

where mm.id in 
(

SELECT mm.id from kbedumoment mm 
left join kbedumomentpostto pt on pt.MOMENT_ID=mm.id 
where mm.deleted_at is NULL 
    && pt.childkey=1005 

union all 

SELECT id from kbedumoment mm 
where POST_TO='school' && mm.deleted_at is NULL && mm.PROJECTKEY =2 

)        


order by mm.id desc 

查询上面需要6.875秒,这需要很长时间。其中子查询花费的时间太长,需要优化

enter image description here

我试过单独执行的子查询。

SELECT mm.id from kbedumoment mm 
left join kbedumomentpostto pt on pt.MOMENT_ID=mm.id 
where mm.deleted_at is NULL 
    && pt.childkey=1005 

union 

SELECT id from kbedumoment mm 
where POST_TO='school' && mm.deleted_at is NULL && mm.PROJECTKEY =2 

结果:

+-------+ 
| id | 
+-------+ 
| 253 | 
| 1264 | 
| 1 | 
| 238 | 
+-------+ 

持续时间:0.109秒。所以子查询没问题。

然后我执行以下测试,用我已经知道的ID替换子查询。

SELECT PROJECTKEY, CONCAT(FIRSTNAME,' ',LASTNAME) as USRCREATED, 
           CONCAT('/userImages/',md.USERKEY,'/',md.IMAGE) as USRCREATED_PROFILE_IMG,mm.DTCREATED 
           FROM kbedumoment mm 
           left join users md on mm.USRCREATED=md.USERKEY 

where mm.id in 
(
1264,253,238,1 
)        


order by mm.id desc 

时间:0.016秒 EXPLAIN enter image description here

这究竟是为什么?

+0

对于这样的情况下,明显的解释失败了,你应该尝试在查询上运行'EXPLAIN'。也许MySQL有一个可以解释行为的步骤。 –

+0

添加了解释后。 – ethan17

+0

不是答案,但由于某些原因,MySQL在最后一个查询中使用了范围扫描,但在实际感兴趣的查询中使用了索引扫描。范围应该超过指数,这可以解释数字。但我不知道如何解决这个问题。当你有更大的表格时,你可能会担心这一点。您的期望可能会发生在更大的数据集上。 –

回答

1

你可以尝试这样的:

SELECT PROJECTKEY, 
    CONCAT(FIRSTNAME, ' ', LASTNAME) AS USRCREATED, 
    CONCAT('/userImages/', md.USERKEY, '/', md.IMAGE) AS USRCREATED_PROFILE_IMG, 
    mm.DTCREATED 
FROM kbedumoment mm 
    INNER JOIN (
     SELECT mm.id 
     FROM kbedumoment mm 
      LEFT JOIN kbedumomentpostto pt ON pt.MOMENT_ID = mm.id 
     WHERE mm.deleted_at IS NULL 
      AND pt.childkey = 1005 
     UNION 
     SELECT id 
     FROM kbedumoment mm 
     WHERE POST_TO = 'school' 
      AND mm.deleted_at IS NULL 
      AND mm.PROJECTKEY = 2 
    ) temp ON temp.id = mm.id 
    LEFT JOIN users md ON mm.USRCREATED = md.USERKEY 
ORDER BY mm.id DESC; 

我这里使用的是用你预先存在有&&子查询和替换它与AND然后用它作为生成表INNER JOIN因为这两个记录必须存在在mmtemp之间。

我也增强了格式,以便您可以更好地阅读查询。干杯

+0

另外,您可以在查询之前添加'SET SESSION tx_isolation ='READ-COMMITTED';'以便您的会话只能读取'提交的'数据 – Avidos

+0

您的解决方案非常完美!非常感谢 ! – ethan17