2014-09-01 71 views
0

我的查詢太長(3-4s)。任何想法如何使這個更快?MySQL Query - alternative

SELECT u.id AS id_uzytkownika, 
     u.login, 
     u.ranga, 
     u.online_light AS online, 

    (SELECT MAX(id) 
    FROM uzytkownicy_zdjecia 
    WHERE id_uzytkownika = u.id 
    AND prywatna =0) AS id_fotki, 

    (SELECT fotka 
    FROM uzytkownicy_zdjecia 
    WHERE id = id_fotki) AS fotka , 

    (SELECT srednia_ocen 
    FROM uzytkownicy_zdjecia 
    WHERE id = id_fotki) AS srednia_ocen, 

    (SELECT ile_ocen 
    FROM uzytkownicy_zdjecia 
    WHERE id = id_fotki) AS ile_ocen 
FROM uzytkownicy u 
WHERE u.foto =1 
    AND u.plec = "mezczyzna" 
ORDER BY srednia_ocen DESC, 
     ile_ocen DESC, 
     id_fotki DESC LIMIT 42 
+1

嘗試使用'Explain'來找出你需要索引的地方。 – Jens 2014-09-01 09:10:55

+2

簡而言之,用['JOIN's](http://dev.mysql.com/doc/refman/5.0/en/join.html)替換子查詢。 – BlitZ 2014-09-01 09:11:51

+0

我試過Join,它運行良好(0,6s),但我不得不添加GROUP BY或DISTINCT到這個,然後最好的時間是(2,5s),所以它仍然太長。 – user2828677 2014-09-01 09:14:27

回答

0

你能解釋一下你的表結構和這個查詢是關於什麼的?由於列名不是英文,大多數讀者可能會有一個問題,理解你在這裏試圖做什麼...

一般來說,它看起來像你有很多嵌套SELECTS這裏到同一個表 - 有什麼特別的理由嗎?

0

試試這個:

SELECT u.id AS id_uzytkownika, 
    u.login, 
    u.ranga, 
    u.online_light AS online, 

(SELECT MAX(id) 
FROM uzytkownicy_zdjecia 
WHERE id_uzytkownika = u.id 
AND prywatna =0) AS id_fotki, 
z.fotka, 
z.srednia_ocen, 
z.ile_ocen 
FROM uzytkownicy u 
JOIN uzytkownicy_zdjecia z 
ON u.id_fotki = z.id 
WHERE u.foto =1 
    AND u.plec = "mezczyzna" 
ORDER BY srednia_ocen DESC, 
    ile_ocen DESC, 
    id_fotki DESC LIMIT 42 

我已經取代3子查詢與聯接。第一個子查詢具有不同的條件,如果可以將該條件與其他查詢合併,則可以刪除該條件。

注重您有一個名爲id_fokta子查詢的結果,但相同的名字有uzytkownicy表

+0

太長,9s ... – user2828677 2014-09-01 09:38:32

+0

你在桌子上使用過索引嗎? – 2014-09-01 09:53:14

+0

@ user2828677:這沒有任何意義。喬的查詢永遠不會比你的查詢花更長的時間。它也是如此,只是以一種更直接的方式。當然在u.id_fotki上有一個外鍵(因此是索引),是嗎?如果沒有,然後添加它。 – 2014-09-01 09:53:22

0

你不必一次又一次地查詢相同的表具有相同條件的主鍵。用簡單的連接來替換你的子選擇。 LEFT JOIN,如果有可能沒有匹配的記錄存在。

SELECT 
    u.id AS id_uzytkownika, 
    u.login, 
    u.ranga, 
    u.online_light AS online, 
    (
    SELECT MAX(id) 
    FROM uzytkownicy_zdjecia 
    WHERE id_uzytkownika = u.id 
    AND prywatna =0 
) AS id_fotki, 
    uz.fotka, 
    uz.srednia_ocen, 
    uz.ile_ocen 
FROM uzytkownicy u 
LEFT JOIN uzytkownicy_zdjecia uz ON uz.id = u.id_fotki 
WHERE u.foto = 1 
    AND u.plec = "mezczyzna" 
ORDER BY u.srednia_ocen DESC, 
     u.ile_ocen DESC, 
     u.id_fotki DESC LIMIT 42 

寫上述查詢的另一種方法是聚集,然後再加入:

SELECT 
    u.id AS id_uzytkownika, 
    u.login, 
    u.ranga, 
    u.online_light AS online, 
    uzz.id_fotki, 
    uz.fotka, 
    uz.srednia_ocen, 
    uz.ile_ocen 
FROM uzytkownicy u 
LEFT JOIN uzytkownicy_zdjecia uz ON uz.id = u.id_fotki 
LEFT JOIN 
(
    SELECT id_uzytkownika, MAX(id) AS id_fotki 
    FROM uzytkownicy_zdjecia 
    WHERE prywatna =0 
    GROUP BY id_uzytkownika 
) uzz ON uzz.id_uzytkownika = u.id 
WHERE u.foto = 1 
    AND u.plec = "mezczyzna" 
ORDER BY u.srednia_ocen DESC, 
     u.ile_ocen DESC, 
     u.id_fotki DESC LIMIT 42 

順便說一句:什麼是「mezczyzna」?一個字符串?那麼這應該是單引號。