MySQL порядок по приоритету - PullRequest
3 голосов
/ 09 марта 2012

Привет, я создаю программу на 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

@ Ливен :

Результаты запроса НЕ одинаковы - без ограничения должно быть ~ 90 тыс. Строк: enter image description here

результатов запроса равны НЕ одинаковы - возвращаем ~ 50 строк: enter image description here

1 Ответ

1 голос
/ 09 марта 2012

Мне трудно прочитать ваш запрос, я бы переформатировал его к этому

переформатирован

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

Теперь для меня это запрос, с которым я могу работать. К сожалению, я не вижу каких-либо явных проблем с производительностью, которые не может решить надлежащая индексация.

Можете ли вы показать нам план выполнения вашего запроса?

...