Использование соединений правильно - PullRequest
1 голос
/ 21 августа 2009

Я ищу совет о том, как оптимизировать это ....

SELECT   u.uid,
         u.username,
         u.nid,
         wd.pay
FROM     (users_data AS u
          LEFT JOIN winners_data wd
            ON u.nid = wd.nid
               AND u.uid = wd.uid)
         LEFT JOIN dp_node dn
           ON u.nid = dn.nid
WHERE    u.uid = ".$val."
         AND ((dn.TYPE = 'event'
               AND (SELECT Count(nid)
                    FROM   tournament_event
                    WHERE  nid = u.nid
                           AND type_value IN ('A','B','C')) > 0)
               OR (dn.TYPE = 'new_event'
                   AND (SELECT Count(nid)
                        FROM   user_tournament_event
                        WHERE  nid = u.nid
                               AND type_0_value IN ('Y','X')) > 0))
ORDER BY nid ASC

На самом деле $ val - это не что иное, как uid, который приходит из следующего запроса по одному как часть моего цикла.

ВЫБЕРИТЕ DISTINCT (dump.uid) ОТ лидера_Jdump AS dump

Есть ли способ добавить эту часть также к вышеуказанному запросу? Я думаю, это будет быстрее, если я смогу сделать это на уровне MySQL.

Ответы [ 3 ]

4 голосов
/ 21 августа 2009

Попробуйте это:

SELECT  u.uid, u.username, u.nid, wd.pay
FROM    users_data AS u
LEFT JOIN
        winners_data wd
ON      (wd.nid, wd.uid) = (u.nid, u.uid)
JOIN    dp_node dn 
ON      dn.nid = u.nid
        AND dn.type IN ('event', 'new_event')
WHERE   u.uid = ".$val."
        AND EXISTS
        (
        SELECT  NULL
        FROM    tournament_event te
        WHERE   te.nid = u.nid
                AND type_value IN ('A', 'B', 'C')
                AND dn.type = 'event'
        UNION ALL
        SELECT  NULL
        FROM    user_tournament_event te
        WHERE   te.nid = u.nid
                AND type_0_value IN ('X', 'Y')
                AND dn.type = 'new_event'

        )
ORDER BY
        u.nid ASC

Я удалил OUTER JOIN из dp_node, поскольку для исходного запроса требовалось условие не NULL для поля dp_node в предложении WHERE, поэтому LEFT JOIN здесь бесполезно.

Создайте следующие индексы:

users_data (uid, nid)
winners_data (uid, nid)
dp_node (nid, event_type)
tournament_event (nid, type_value)
user_tournament_event (nid, type_0_value)
0 голосов
/ 21 августа 2009

Я видел этот стиль (все закрывающие скобки в конце одной строки) и удивляюсь, как люди могут понять его. Кто-то ранее спрашивал о переформатированной версии:

SELECT    u.uid,
          u.username,
          u.nid,
          wd.pay
FROM      users_data u
          LEFT JOIN winners_data wd
               ON u.nid = wd.nid
               AND u.uid = wd.uid
          LEFT JOIN dp_node dn
               ON u.nid = dn.nid
WHERE     u.uid = ".$val."
          AND (
                (
                    dn.TYPE = 'event'
                    AND (
                        SELECT Count(nid)
                        FROM   tournament_event
                        WHERE  nid = u.nid
                               AND type_value IN ('A','B','C')
                    ) > 0
                )
                OR (
                    dn.TYPE = 'new_event'
                    AND (
                        SELECT Count(nid)
                        FROM   user_tournament_event
                        WHERE  nid = u.nid
                               AND type_0_value IN ('Y','X')
                    ) > 0
                )
          )
ORDER BY  nid ASC
0 голосов
/ 21 августа 2009

Это может быть эквивалентно, но легче для чтения:

WITH NIDs(type_value,nid) AS (
  SELECT 'event', nid FROM tournament_event
  WHERE type_value IN ('A','B','C')
  UNION ALL
  SELECT 'new_event', nid FROM user_tournament_event
  WHERE type_value IN ('X','Y')
)

SELECT
  u.uid,
  u.username,
  u.nid,
  wd.pay
FROM users_data AS u JOIN NIDs AS n
ON n.nid = u.nid
AND n.type_value = u."type"
LEFT JOIN winners_data AS wd
ON u.nid=wd.nid AND u.uid=wd.uid
LEFT JOIN dp_node AS dn 
ON u.nid = dn.nid
WHERE u.uid=".$val."
ORDER BY nid ASC

Если «какое событие» является важным, вам лучше использовать одну таблицу, из которой вы можете сделать это определение, посмотрев на один или два столбца. Похоже, у вас есть две таблицы, содержащие эту информацию (tour_event и user_tournament_event). Например, вы можете хранить информацию, как в выражении NID этого запроса.

Добавлено 2009-08-22:

Вот тот же запрос с CTE, выраженным как производная таблица:

SELECT
  u.uid,
  u.username,
  u.nid,
  wd.pay
FROM users_data AS u JOIN (
  SELECT 'event', nid FROM tournament_event
  WHERE type_value IN ('A','B','C')
  UNION ALL
  SELECT 'new_event', nid FROM user_tournament_event
  WHERE type_value IN ('X','Y')
) AS n(type_value,nid)
ON n.nid = u.nid
AND n.type_value = u."type"
LEFT JOIN winners_data AS wd
ON u.nid=wd.nid AND u.uid=wd.uid
LEFT JOIN dp_node AS dn 
ON u.nid = dn.nid
WHERE u.uid=".$val."
ORDER BY nid ASC
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...