2017-06-23 2 views
0

Ich versuche, die folgende mysql Abfrage zu optimieren. Es läuft in etwa 2,5 Sekunden. Ich habe gelesen, zusammengesetzte Indizes, aber ich hoffe, jemand kann mir helfen, zu verstehen, wie Sie zusammengesetzte Indizes mit Abfragen wie diese, die mehrere Joins, viele, wo Bedingungen (einschließlich Datumsbereiche), eine Gruppe von und eine Reihenfolge von auf ein berechneter Wert. Fehle ich einen nützlichen zusammengesetzten Index? Gibt es einen effizienteren Weg, Daten aus diesen Tabellen zu ziehen? Jede Hilfe wird sehr geschätzt!Compound Index Reihenfolge MySQL Query

SELECT 
branch.name AS branch, 
SUM(appointment.status = 'completed') AS `Completed`, 
SUM(appointment.status = 'cancelled') AS `Cancelled`, 
SUM(appointment.status = 'not completed') AS `Not Completed`, 
SUM(appointment.status != 'rescheduled') AS `Total` 
FROM rep 
JOIN customer ON rep.id = customer.rep_id 
JOIN office ON rep.office_id = office.id 
JOIN appointment ON customer.id = appointment.customer_id 
JOIN branch ON office.branch_id = branch.id 
WHERE rep.active= 1 
AND rep.group IN (1,2,3) 
AND rep.deleted = 0 
AND customer.saved = 0 
AND (customer.rep_id != appointment.closed_by OR appointment.closed_by IS NULL) 
AND customer.rep_id != 0 
AND customer.deleted = 0 
AND office.visible = 1 
AND office.deleted = 0 
AND appointment.date >= '2016-12-01' 
AND appointment.date < '2017-11-30' 
AND appointment.current = 1 
GROUP BY branch.id 
ORDER BY Completed 

Hier ist die Ausgabe von EXPLAIN:

id: 1 
select_type: simple 
table: office 
type: ref 
possible_keys: PRIMARY, deleted_branchID_name, deleted_visible 
key: deleted_visible 
key_len: 5 
ref: const,const 
rows: 73 
Extra: Using index condition; Using temporary; Using filesort 

id: 1 
select_type: simple 
table: branch 
type: eq_ref 
possible_keys: PRIMARY 
key: PRIMARY 
key_len: 4 
ref: office.branch_id 
rows: 1 
Extra: NULL 

id: 1 
select_type: simple 
table: rep 
type: ref 
possible_keys: PRIMARY, group_id, office_id, active_deleted 
key: office_id 
key_len: 5 
ref: office.id 
rows: 57 
Extra: Using index condition; Using where 

id: 1 
select_type: simple 
table: customer 
type: ref 
possible_keys: PRIMARY, rep_id 
key: rep_id 
key_len: 4 
ref: rep.id 
rows: 61 
Extra: Using where 

id: 1 
select_type: simple 
table: appointment 
type: ref 
possible_keys: date, customer_id, closedByID_date, isCurrent_date 
key: customer_id 
key_len: 4 
ref: customer.id 
rows: 1 
Extra: Using where 
+0

Ohne etwas über Ihre Daten zu wissen, Ihre Abfrage schlägt die index 'office (gelöscht, sichtbar, Zweig_ID)'. Diese Tabelle scheint jedoch nur eine Handvoll Zeilen zu enthalten, und daher wird dieser Index wahrscheinlich nicht viel helfen; Um eine bessere Strategie zu wählen, können Sie versuchen, starke Filter zu identifizieren. Wenn z.B. 99% Ihrer Daten haben 'customer.saved = 1' oder' termination.current! = 1', Sie können versuchen, dies zu verwenden, um Ihre Anfrage zu optimieren - aber es hängt von Ihren Daten ab. Außerdem sollten Sie bis auf Klarheit alle bis auf den letzten linken Join durch einen Join ersetzen (und den letzten auch, wenn office.branch_id 'not null' ist). – Solarflare

Antwort

0

Ein Vorschlag

unuseful entfernen() um unter der Bedingung

LEFT JOIN customer ON rep.id = customer.rep_id 
    LEFT JOIN office ON rep.office_id = office.id 
    LEFT JOIN appointment ON customer.id = appointment.customer_id 
    LEFT JOIN branch ON office.branch_id = branch.id