2012-03-09 151 views
3

嗨,我正在構建一個Java程序,我需要管理一些項目。爲了做到這一點,我需要過濾項目。我通過構建SQL查詢並執行它來過濾項目。我需要以下查詢首先排序 (LEFT JOIN (SELECT * FROM grupe ORDER BY grupe.pavadinimas DESC)grupe ON) 並且只有然後添加所有其他數據並執行WHERE子句。MySQL按優先順序排列

SELECT * 
FROM (
     (
     SELECT preke.* 
     FROM preke_tiekejas 
       , preke 
     WHERE preke_tiekejas.tiek_id IN (18610,13604) 
       AND preke.pr_id=preke_tiekejas.pr_id 
     GROUP BY 
       preke_tiekejas.pr_id 
    ) preke 
     , preke_kaina 
     , (
     SELECT * 
     FROM preke_info 
     WHERE preke_info.pavadinimas LIKE '%kait%' 
    ) preke_info 
    ) LEFT JOIN (
     SELECT * 
     FROM grupe 
     ORDER BY 
       grupe.pavadinimas DESC 
    )grupe ON grupe.pgs_id=preke.pgs_id 
    LEFT JOIN gamintojas ON gamintojas.gam_id=preke.gam_id 
    LEFT JOIN grupe_darb ON grupe_darb.pgs_id=grupe.pgs_id 
WHERE preke_kaina.pr_id=preke.pr_id 
    AND preke_info.pr_id=preke.pr_id 
    AND grupe_darb.darb_id = 20 
LIMIT 0, 500 

如果我刪除這些兩個子查詢:

(SELECT * FROM preke_info WHERE preke_info.pavadinimas LIKE '%kait%') 

(SELECT preke.* FROM preke_tiekejas, preke 
WHERE preke_tiekejas.tiek_id IN (18610,13604) 
AND preke.pr_id=preke_tiekejas.pr_id 
GROUP BY preke_tiekejas.pr_id) 

那麼查詢的工作就是我想要的。

P.S.命令它只在查詢結束時不是一個選項,因爲有大量的記錄,然後它變得緩慢地獄。

解釋

http://i40.tinypic.com/wirbz6.jpg

@Lieven

查詢的結果是不相同 - 無極限應爲〜90K行: enter image description here

查詢結果一樣 - 迴歸〜50rows: enter image description here

回答

1

我覺得很難讀您的查詢,我將其重新格式化爲這個

重新格式化

SELECT * 
FROM (
      (
      SELECT preke.* 
      FROM preke_tiekejas 
        , preke 
      WHERE preke_tiekejas.tiek_id IN (18610,13604) 
        AND preke.pr_id=preke_tiekejas.pr_id 
      GROUP BY 
        preke_tiekejas.pr_id 
     ) preke 
      , preke_kaina 
      , (
      SELECT * 
      FROM preke_info 
      WHERE preke_info.pavadinimas LIKE '%kait%' 
     ) preke_info 
     ) LEFT JOIN (
      SELECT * 
      FROM grupe 
      ORDER BY 
        grupe.pavadinimas DESC 
     )grupe ON grupe.pgs_id=preke.pgs_id 
     LEFT JOIN gamintojas ON gamintojas.gam_id=preke.gam_id 
     LEFT JOIN grupe_darb ON grupe_darb.pgs_id=grupe.pgs_id 
WHERE preke_kaina.pr_id=preke.pr_id 
     AND preke_info.pr_id=preke.pr_id 
     AND grupe_darb.darb_id = 20 
LIMIT 0, 500 

重新格式化之後,我會刪除隱含的JOIN語法。你應該總是嘗試使用明確的JOIN的可讀性和可維護性。隱含的JOIN語法遲早會過時。

使用明確連接

SELECT * 
FROM ((
      SELECT preke.* 
      FROM preke_tiekejas 
        INNER JOIN preke ON preke.pr_id=preke_tiekejas.pr_id 
      WHERE preke_tiekejas.tiek_id IN (18610,13604)      
      GROUP BY 
        preke_tiekejas.pr_id 
     ) preke 
      INNER JOIN preke_kaina preke_kaina.pr_id=preke.pr_id 
      INNER JOIN (
      SELECT * 
      FROM preke_info 
      WHERE preke_info.pavadinimas LIKE '%kait%' 
     ) preke_info ON preke_info.pr_id=preke.pr_id 
     ) LEFT JOIN (
      SELECT * 
      FROM grupe 
      ORDER BY 
        grupe.pavadinimas DESC 
     )grupe ON grupe.pgs_id=preke.pgs_id 
     LEFT JOIN gamintojas ON gamintojas.gam_id=preke.gam_id 
     LEFT JOIN grupe_darb ON grupe_darb.pgs_id=grupe.pgs_id 
WHERE grupe_darb.darb_id = 20 
LIMIT 0, 500 

現在冗餘子查詢中脫穎而出。我可能會關閉,但我相信你的說法可以進一步降低該

刪除冗餘的子查詢

SELECT * 
FROM (
      SELECT preke.* 
      FROM preke_tiekejas 
        INNER JOIN preke ON preke.pr_id=preke_tiekejas.pr_id 
      WHERE preke_tiekejas.tiek_id IN (18610,13604)      
      GROUP BY 
        preke_tiekejas.pr_id 
     ) preke 
     INNER JOIN preke_kaina preke_kaina.pr_id=preke.pr_id 
     INNER JOIN preke_info ON preke_info.pr_id=preke.pr_id 
     LEFT OUTER JOIN grupe ON grupe.pgs_id=preke.pgs_id 
     LEFT OUTER JOIN gamintojas ON gamintojas.gam_id=preke.gam_id 
     LEFT OUTER JOIN grupe_darb ON grupe_darb.pgs_id=grupe.pgs_id 
WHERE grupe_darb.darb_id = 20 
     AND preke_info.pavadinimas LIKE '%kait%' 
ORDER BY 
     grupe.pavadinimas DESC 
LIMIT 0, 500 

現在,對我來說,這是一個查詢我可以工作。不幸的是,我沒有看到任何明顯的性能問題,即正確的索引無法解決。

你能告訴我們你的查詢的執行計劃嗎?

+1

如果我理解正確,這就是你想要的:http://i44.tinypic.com/ibl64i.jpg – Minutis 2012-03-09 07:40:55

+0

@Minutis - 是的。我已將它添加到您的問題。你能否驗證我的修改後的聲明是否提供了與原始查詢相同的結果? – 2012-03-09 07:53:05

+0

@Minutis - 現在我是閱讀MySQL解釋計劃的外行,但是在我看來,你錯過了'grupe_darb'上的索引。 – 2012-03-09 07:58:46