【问题标题】:Mysql GROUP BY and ORDER BY DESC [duplicate]Mysql GROUP BY 和 ORDER BY DESC [重复]
【发布时间】:2013-09-20 18:54:58
【问题描述】:

这是我的完整查询:

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 组中的每个客户(客户可以在不同的组中)获取一个最后添加的行。

谢谢。

【问题讨论】:

  • DESCRIBE / EXPLAIN 对该查询显示什么?
  • 另外,从那里删除SELECT * ...。选择特定列。它可能会增加开销。 SELECT * 可能是真正的速度杀手。

标签: php mysql sql group-by sql-order-by


【解决方案1】:

要获取“组 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 

如果contactIdcontacts 中的PK,则不需要第二个连接子句。

默认情况下,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

【讨论】:

  • ORDER BY NULL 的意义何在?
  • @GarethD 是一个优化,分组数据时基本上不会使用filesort
  • @CORRUPT 抱歉打错了,现在已修复,谢谢
  • 每天都是上学日!我认为这很奇怪,但是你去吧,这仍然是我学到的新东西。谢谢。
  • @GarethD 这就是我喜欢 stackoverflow 的原因,因为你每天都能学到新东西:D
猜你喜欢
  • 2020-03-09
  • 1970-01-01
  • 1970-01-01
  • 2021-02-22
  • 2015-02-26
  • 2020-06-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多