MySQL: Czy mogę wykonać lewe połączenie i wyciągnąć tylko jeden wiersz z tabeli łączenia?

Napisałem niestandardowe biuro pomocy do pracy i działa świetnie ... do niedawna. Jedno zapytanie manaprawdę zwolnił. Teraz trwa około 14 sekund! Oto odpowiednie tabele:

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;

Gdy użytkownik prześle bilet, trafia do tabeli „bilety”. Następnie, gdy agenci przechodzą przez problem, rejestrują działania, które podjęli. Każdy wpis przechodzi do tabeli „rozwiązania”. Innymi słowy, bilety mają wiele rozwiązań.

Celem spowolnionego zapytania jest pobranie wszystkich pól z tabeli „bilety”, a także ostatniego wpisu z tabeli „rozwiązania”. To jest zapytanie, którego używałem:

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

Oto przykład tego, jak wygląda pole „latest_solution_entry”:

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

W PHP dzielę pole „latest_solution_entry” i formatuję je poprawnie.

Kiedy zauważyłem, że strona, na której działa zapytanie, zwolniłasposób w dół uruchomiłem zapytanie bez podzapytania i było super szybko. Potem uruchomiłemEXPLAIN w pierwotnym zapytaniu i otrzymałem to:

+----+--------------------+-----------+-------+---------------+-----------+---------+---------------------+-------+-----------------------------+
| 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 |
+----+--------------------+-----------+-------+---------------+-----------+---------+---------------------+-------+-----------------------------+

Więc szukam sposobu, aby uczynić moje zapytanie bardziej wydajnym, a jednocześnie osiągnąć ten sam cel. Jakieś pomysły?

questionAnswers(4)

yourAnswerToTheQuestion