1

I have the following table: http://pastebin.com/XH6FvhZ8

and the following query:

SELECT *
FROM (SELECT *
      FROM `job_logs`
      ORDER BY id DESC) AS job_logs_tmp
WHERE (job_logs_tmp.user_id = ? AND job_logs_tmp.workflow_state = ?)
GROUP BY chain, subchain, job_type

here is the explain of this query: http://pastebin.com/AjXgzRBA

this query usually takes over 4K ms to execute, any ideas how I can speed the query execution? I have no problem adding indexes to table if needed

thanks!

3
  • 1
    You want a greatest-n-per-group query. Search the SO site for this tag and you'll find plenty of similar queries and answers. Commented Apr 28, 2012 at 15:00
  • remove the ORDER BY id DESC... the group by will destroy the ordering anyway.
    – Ben
    Commented Apr 29, 2012 at 17:21
  • @Ben: Not in MySQL ... Commented Apr 29, 2012 at 17:29

2 Answers 2

1

What are you trying to achieve here? I am not a MySQL programmer; however, as I understand SQL in general, every column that is not listed in the GROUP BY clause must be part of an aggregate like

SELECT
    MAX(id) AS max_id,
    chain, subchain, job_type
FROM
    `job_logs`
WHERE
    user_id = ? AND
    workflow_state = ?
GROUP BY
    chain, subchain, job_type 

SELECT * in a grouping query will not work in most (if not all) SQL implementations.


UPDATE

In order to get the row with the highest id for each group you would have to embed the query above in an "outer" query.

SELECT *
FROM `job_logs`
WHERE id IN (
    SELECT
        MAX(id) AS max_id
    FROM
        `job_logs`
    WHERE
        user_id = ? AND
        workflow_state = ?
    GROUP BY
        chain, subchain, job_type 
)

This query is deterministic and should work with most SQL dialects.


Some query engines perform better with joins than with "IN subquery". You can give this a try

SELECT A.*
FROM
    `job_logs` A
    INNER JOIN (
        SELECT
            MAX(id) AS max_id
        FROM
            `job_logs`
        WHERE
            user_id = ? AND
            workflow_state = ?
        GROUP BY
            chain, subchain, job_type) B
    ON A.id = B.max_id;
5
  • In MySQL it works. The query would return one row per group (the one with highest id). Commented Apr 28, 2012 at 17:00
  • @ypercube: I missed this possibility from other implementations! Commented Apr 28, 2012 at 17:35
  • 1
    @ypercube: "works" is relative. It will return non-deterministic results.
    – user1822
    Commented Apr 29, 2012 at 17:55
  • @a_horse_with_no_name: I don't disagree on that. I should have said something like: "It works, now, but one never knows when it will break." Commented Apr 30, 2012 at 12:28
  • I don't know if my new query solves the performance problems (it depends on how the query optimizer works), but it should solve the non-deterministic problem mentioned by a_horse_with_no_name. Commented Apr 30, 2012 at 13:50
-2

Try this:

SELECT 
  *
FROM (
  SELECT *
  FROM `job_logs`
  WHERE user_id = ? AND workflow_state = ?
  ORDER BY id DESC
  ) tmp
GROUP BY chain, subchain, job_type
1
  • 1
    Could you at least explain why you think this is better? (Also, please use CTRL+K or the {} button for code samples, not HTML tags.) Commented Jan 12, 2018 at 13:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.