2014-05-25 168 views
0

我可以以任何不同的方式使用此代碼來獲得更好的性能嗎?Mysql子查詢優化?

我試過這種方式;

SELECT K.id, M.m_id, K.Sil, K.Banli, K.Foto, K.KullaniciAdi, K.Ad, K.Soyad, K.Gender, 
(select rate_id,Rate,Zaman from ratings where UyeID=K.id ORDER BY rate_id DESC LIMIT 1) 

但我不能做我想做的事。

這是工作代碼。給人的結果,我想:

SELECT K.id, M.m_id, K.Sil, K.Banli, K.Foto, K.KullaniciAdi, K.Ad, K.Soyad, K.Gender, 
     ( SELECT R.mr_id FROM mesajlarreply R 
      WHERE R.CID=M.m_id 
      ORDER BY R.mr_id DESC LIMIT 1 
     ) as mr_id, 
     ( SELECT R.Mesaj FROM mesajlarreply R 
      WHERE R.CID=M.m_id 
      ORDER BY R.mr_id DESC LIMIT 1 
     ) as Mesaj, 
     ( SELECT R.KayitZaman FROM mesajlarreply R 
      WHERE R.CID=M.m_id 
      ORDER BY R.mr_id DESC LIMIT 1 
     ) as KayitZaman 
FROM mesajlar M, kullanicilar K 
WHERE 
    CASE 
     WHEN M.K1 = '1' THEN M.K2 = K.id 
     WHEN M.K2 = '1' THEN M.K1 = K.id 
    END 
    AND (M.K1 = '1' OR M.K2 = '1') 
ORDER BY M.m_id DESC 
LIMIT 20 
+0

你可以發佈兩個表的結構嗎?或者至少請附上關於主鍵主鍵的信息 - 哪些列是這兩個表中的主鍵? – krokodilko

+0

您的編輯會使這看起來是一個新的/不同的查詢。如果是這樣,你應該能夠適應我的答案爲新的查詢;如果您遇到問題,請發佈一個_新問題。 –

+0

@ Clockwork-Muse我發佈了一個新問題,但nobodys幫助我。我怎樣才能做到這一點? http://stackoverflow.com/questions/23901430/mysql-subquery-optimize?noredirect=1#comment36808675_23901430 –

回答

0

假設子查詢的順序是應該是相同的(不是筆誤),那麼三者的結合是一個問題。 MySQL有這幾種現有的解決方案,如果行,每個組的數量小,所以我想我更喜歡在this answer的風格,這對於你的情況應該是這樣的:

SELECT rToUse.mr_id, rToUse.mesaj, rToUse.kayitZaman 
FROM Mesajlarreply rToUse 
LEFT JOIN Mesajlarreply rKnockout 
     ON rKnockout.cId = rToUse.cId AND rToUse.mr_id < rKnockout.mr_id 
WHERE rKnockout.mr_id IS NULL 

(這工作,因爲當行被連接,最大的那個mr_id沒有匹配,因爲rKnockout.mr_id IS NULL爲真,所有其他行然後被丟棄)
你使用三個子查詢的事實可能是在系統上做一個數字。

CASE語句評估爲一組簡單的布爾條件:

(M.k1 = '1' AND M.k2 = K.id) OR (M.k1 <> '1' AND M.k2 = '1' AND M.k1 = K.id) 

...我會假設你不具備的情況下​​k2等於'1'同時,所以M.k1 <> '1'(這是爲了保留CASE的語義,如果真)是不必要的。請注意,OR s仍然可能是一個表現痛點。而且,如果這些列中的任何一個實際上是某種數字類型,則連接首先需要轉換,這可能會導致性能下降。
我已經使用了LEFT JOIN子查詢 - (未提供數據集中未經檢驗的,當然)保存

SELECT K.id, M.m_id, K.sil, K.banli, K.foto, K.kullaniciAdi, K.ad, K.soyad, K.gender, 
     R.mr_id, r.mesaj, r.kayitZaman 
FROM Mesajlar M 
JOIN Kullanicilar K 
    ON (M.k1 = '1' AND M.k2 = K.id) 
     OR (M.k2 = '1' AND M.k1 = K.id) 
LEFT JOIN (SELECT rToUse.cId, rToUse.mr_id, rToUse.mesaj, rToUse.kayitZaman 
      FROM Mesajlarreply rToUse 
      LEFT JOIN Mesajlarreply rKnockout 
        ON rKnockout.cId = rToUse.cId 
        AND rToUse.mr_id < rKnockout.mr_id 
      WHERE rKnockout.mr_id IS NULL) R 
     ON R.cId = M.m_id 
ORDER BY M.m_id DESC 
LIMIT 20 

所以,我可能會通過寫這樣的查詢開始給定數據語義。如果你有所有情況下的行(或只關心那些人),它可以改爲(INNER) JOIN。根據你的數據集的佈局(以及你有/沒有的索引),這可能不會有更好的表現,但是這通常應該對優化器更友好。

+0

我重新編輯我的帖子 –

+0

你能再次讀我的問題嗎? –