MySQL按优先顺序排序

时间:2012-03-09 06:56:53

标签: mysql sql-order-by

您好我正在构建一个Java程序,我需要管理一些项目。为了做到这一点,我需要过滤项目。我通过构建SQL查询并执行它来过滤项目。我需要以下查询来进行排序 (LEFT JOIN (SELECT * FROM grupe ORDER BY grupe.pavadinimas DESC)grupe ON)  然后只添加所有其他数据并执行WHERE子句。

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

查询结果 NOT 相同 - 没有限制应该是~90k行: enter image description here

查询结果 NOT 相同 - 返回~50rows: enter image description here

1 个答案:

答案 0 :(得分: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语法迟早会过时。

使用显式JOINS

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

现在,对我来说,这是一个我可以使用的查询。不幸的是,我没有看到任何明显的性能问题,正确的索引无法解决。

您能告诉我们您的查询的执行计划吗?