MySQL: Kann ich einen Left-Join durchführen und nur eine Zeile aus der Join-Tabelle ziehen?

Ich habe einen benutzerdefinierten Helpdesk für die Arbeit geschrieben und er lief bis vor kurzem großartig. Eine Abfrage hatJa wirklich verlangsamt. Es dauert jetzt ungefähr 14 Sekunden! Hier sind die relevanten Tabellen:

CREATE TABLE `tickets` (
  `id` int(11) unsigned NOT NULL DEFAULT '0',
  `date_submitted` datetime DEFAULT NULL,
  `date_closed` datetime DEFAULT NULL,
  `first_name` varchar(50) DEFAULT NULL,
  `last_name` varchar(50) DEFAULT NULL,
  `email` varchar(50) DEFAULT NULL,
  `description` text,
  `agent_id` smallint(5) unsigned NOT NULL DEFAULT '1',
  `status` smallint(5) unsigned NOT NULL DEFAULT '1',
  `priority` tinyint(4) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`),
  KEY `date_closed` (`date_closed`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `solutions` (
  `id` int(10) unsigned NOT NULL,
  `ticket_id` mediumint(8) unsigned DEFAULT NULL,
  `date` datetime DEFAULT NULL,
  `hours_spent` float DEFAULT NULL,
  `agent_id` smallint(5) unsigned DEFAULT NULL,
  `body` text,
  PRIMARY KEY (`id`),
  KEY `ticket_id` (`ticket_id`),
  KEY `date` (`date`),
  KEY `hours_spent` (`hours_spent`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Wenn ein Benutzer ein Ticket einreicht, wird es in die Tabelle "Tickets" eingetragen. Während die Agenten das Problem bearbeiten, zeichnen sie die von ihnen ergriffenen Maßnahmen auf. Jeder Eintrag geht in die Tabelle "Lösungen". Mit anderen Worten, Tickets haben viele Lösungen.

Ziel der verlangsamten Abfrage ist es, alle Felder aus der Tabelle "tickets" und auch den neuesten Eintrag aus der Tabelle "solutions" abzurufen. Dies ist die Abfrage, die ich verwendet habe:

SELECT tickets.*,
    (SELECT CONCAT_WS(" * ", DATE_FORMAT(solutions.date, "%c/%e/%y"), solutions.hours_spent, CONCAT_WS(": ", solutions.agent_id, solutions.body))
    FROM solutions
    WHERE solutions.ticket_id = tickets.id
    ORDER BY solutions.date DESC, solutions.id DESC
    LIMIT 1
) AS latest_solution_entry
FROM tickets
WHERE tickets.date_closed IS NULL
OR tickets.date_closed >= '2012-06-20 00:00:00'
ORDER BY tickets.id DESC

Hier ist ein Beispiel dafür, wie das Feld "latest_solution_entry" aussieht:

6/20/12 * 1337 * 1: I restarted the computer and that fixed the problem. Yes, I took an hour to do this.

In PHP habe ich das Feld "latest_solution_entry" aufgeteilt und richtig formatiert.

Als ich bemerkte, dass die Seite, auf der die Abfrage ausgeführt wird, langsamer wurdeWeg Ich habe die Abfrage ohne die Unterabfrage ausgeführt und sie war superschnell. Ich lief dann einEXPLAIN auf die ursprüngliche Abfrage und bekam diese:

+----+--------------------+-----------+-------+---------------+-----------+---------+---------------------+-------+-----------------------------+
| id | select_type        | table     | type  | possible_keys | key       | key_len | ref                 | rows  | Extra                       |
+----+--------------------+-----------+-------+---------------+-----------+---------+---------------------+-------+-----------------------------+
|  1 | PRIMARY            | tickets   | index | date_closed   | PRIMARY   | 4       | NULL                | 35804 | Using where                 |
|  2 | DEPENDENT SUBQUERY | solutions | ref   | ticket_id     | ticket_id | 4       | helpdesk.tickets.id |     1 | Using where; Using filesort |
+----+--------------------+-----------+-------+---------------+-----------+---------+---------------------+-------+-----------------------------+

Daher suche ich nach einer Möglichkeit, meine Abfrage effizienter zu gestalten und dennoch das gleiche Ziel zu erreichen. Irgendwelche Ideen?

Antworten auf die Frage(4)

Ihre Antwort auf die Frage