子查询需要太长时间,需要优化

时间:2017-10-06 05:58:17

标签: mysql performance

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秒 说明 enter image description here

为什么会这样?

1 个答案:

答案 0 :(得分: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的生成表,因为两个记录必须存在于mm之间{1}}和temp

我还增强了格式,以便您可以更好地查看查询。干杯