2013-09-16 8 views
7

Это мой полный запрос:Mysql GROUP BY и ORDER BY DESC

SELECT * FROM `clientgroupassign` 
LEFT JOIN `clients` ON `clientgroupassign`.clientId = `clients`.clientId 
LEFT JOIN `users` ON `carerId` = `userId` 
LEFT JOIN 
    (SELECT * FROM 
     (SELECT * FROM `contacts` WHERE `contactGroup` = 4 ORDER BY `contactId` DESC) 
     as `contacts` 
    GROUP BY (`contactClientId`) 
    ) AS `contacts` ON `contactClientId` = `clients`.clientId 
WHERE groupId = 4 
ORDER BY `clients`.clientId 

Существует проблема с третьей присоединиться вызывает сценарий, чтобы выполнить в течение примерно 1 минуты. Когда я запускаю его отдельно в PMA:

SELECT * FROM (SELECT * FROM `contacts` WHERE `contactGroup` = 4 ORDER BY `contactId` DESC) AS `contacts` GROUP BY (`contactClientId`) 

все еще выполняется очень долго.

Я хочу получить одну, последнюю добавленную строку от contacts для каждого клиента, который находится в группе 4 (клиент может быть в разных группах).

Спасибо.

+1

Что DESCRIBE'/'' EXPLAIN' шоу для этого запроса? – BlitZ

+2

Также удалите 'SELECT * ...' оттуда. Выберите конкретные столбцы. Это может добавить накладные расходы. 'SELECT * 'может быть настоящим убийцей скорости. – BlitZ

ответ

6

Чтобы получить «Последние добавленные строки из списка контактов, для каждого клиента, который находится в группе 4», попробуйте следующее:

SELECT 
    c.* 
FROM(
    SELECT 
     contactClientId, 
     MAX(contactId) as cid 
    FROM 
     contacts 
    WHERE 
     contactGroup = 4 
    GROUP BY 
     contactClientId 
    ORDER BY 
     NULL 
) as tmp 
INNER JOIN contacts as c 
    ON c.contactId = tmp.cid 
    AND c.contactClientId = tmp.contactClientId 

Если contactId является PK в contacts тогда второй присоединиться пункт не требуется.

По умолчанию MySQL сортирует все GROUP BY col1, col2, ... запросы, как если бы вы указано ORDER BY col1, col2, ... в запросе, а также. Если вы содержат предложение ORDER BY явно, которое содержит тот же столбец , MySQL оптимизирует его без каких-либо ограничений скорости, хотя сортировка все еще происходит. Если запрос включает GROUP BY, но вы хотите, чтобы избежать накладных расходов на сортировку результата, вы можете подавить сортировку по с указанием ORDER BY NULL.

docs.

Полный запрос:

SELECT * FROM `clientgroupassign` 
LEFT JOIN `clients` ON `clientgroupassign`.clientId = `clients`.clientId 
LEFT JOIN `users` ON `carerId` = `userId` 
LEFT JOIN 
    (
     SELECT 
      c.* 
     FROM(
      SELECT 
       contactClientId, 
       MAX(contactId) as cid 
      FROM 
       contacts 
      WHERE 
       contactGroup = 4 
      GROUP BY 
       contactClientId 
      ORDER BY 
       NULL 
     ) as tmp 
     INNER JOIN contacts as c 
      ON c.contactId = tmp.cid 
      AND c.contactClientId = tmp.contactClientId 
    ) AS `contacts` ON `contactClientId` = `clients`.clientId 
WHERE groupId = 4 
ORDER BY `clients`.clientId 
+1

Какой смысл в 'ORDER BY NULL'? – GarethD

+1

@GarethD его оптимизация, в основном filesort не будет использоваться при группировке данных – Stephan

+1

@CORRUPT извините за опечатку, исправлено сейчас, thx – Stephan