2017-10-06 185 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