2017-02-01 3 views
0

Ich habe folgendes Problem:mysql langsame Abfrage Ausgabe

Es gibt 2 MySQL-Datenbanken Database_1, die das Original und Database_2 ist, die auf der ersten Datenbank mit nur wenigen Änderungen (einige neue Spalten, verschiedene Daten) basiert .

Wenn ich eine Abfrage ausführen, die 3 Tabellen aus Datenbank enthält, erhalte ich sehr unterschiedliche Leistungsergebnisse. Ich habe beide Datenbanken auf demselben Localhost-Server getestet.

Abfrage:

SELECT `Applicant`.`id`, `Applicant`.`name`, `User`.`login`, `User`.`id`, Project.id 
FROM `applicants` AS `Applicant` 
LEFT JOIN `authake_users` AS `User` ON (`Applicant`.`authake_user_id` = `User`.`id`) 
LEFT JOIN `projects` AS `Project` ON (`Project`.`applicant_id` = `Applicant`.`id`) 
WHERE `User`.`login` LIKE _latin1 '%1000%' AND `Project`.`id` IS NULL; 

Abfrageausführungszeit:

Database_1 - 0,3 s - diese Datenbank ist die größere obwohl es ist schneller

Database_2 - 1 min 40 s

Alle 3 Tabellen benutzen MyISAM Engine. Tabellen Bewerber und Projekte haben charset utf8, Tabelle authake_users hat charset latin1.

Ich habe die Indizes überprüft (beide Datenbanken haben genau die gleichen Indizes), baute sie um und benutzte ANALYZE und OPTIMIZE auf allen 3 Tabellen ohne Erfolg.

Der einzige Unterschied ich gefunden habe, ist unten zeigen, wenn ich die Abfrage ausführen mit dem Befehl vor ERKLÄREN:

Database_1 enter image description here

Database_2 enter image description here

Hat jemand eine Ahnung, was zu suchen? Was kann einen solchen Unterschied in der Leistung verursachen?

+0

Überprüfen Sie Indizes, möglicherweise aufgrund der Anzahl der Datensätze Unterschied. –

+0

Haben Sie die Möglichkeit, meine Antwort unten zu überprüfen? Bitte probiere es aus und aktualisiere es. –

Antwort

1

Denken Sie daran, dass MySql Query Analyzer Optimierungsplan basierend auf verfügbaren Ressourcen Speicher wählt. Die wechselnde Reihenfolge der Tabellen und ihre JOIN-Pläne helfen jedoch, einen besseren Plan zu wählen.

Ich habe keinen Zugriff auf die Datenbank plus ich bin nicht bewusst, die Ausgabe, die Sie von dieser Abfrage benötigen, deshalb kann keine Analyse durchgeführt werden. Aber einige Vorschläge folgen können Sie versuchen,

Ihre Anfrage ohne WHERE

SELECT `Applicant`.`id`, `Applicant`.`name`, `User`.`login`, `User`.`id`, Project.id 
FROM `applicants` AS `Applicant` 
LEFT JOIN `authake_users` AS `User` 
    ON `Applicant`.`authake_user_id` = `User`.`id` 
    AND `User`.`login` LIKE _latin1 '%1000%' 
LEFT JOIN `projects` AS `Project` 
    ON `Project`.`applicant_id` = `Applicant`.`id` 
    AND `Project`.`id` IS NULL; 

Durch die Reihenfolge der JOINS zu ändern und ohne WHERE

SELECT `Applicant`.`id`, `Applicant`.`name`, `User`.`login`, `User`.`id`, Project.id 
FROM `authake_users` AS `User` 
LEFT JOIN `applicants` AS `Applicant` 
    ON `Applicant`.`authake_user_id` = `User`.`id` 
    AND `User`.`login` LIKE _latin1 '%1000%' 
LEFT JOIN `projects` AS `Project` 
    ON `Project`.`applicant_id` = `Applicant`.`id` 
    AND `Project`.`id` IS NULL; 

Ihre Anfrage im Auftrag von JOINS Wechsel - 1

SELECT `Applicant`.`id`, `Applicant`.`name`, `User`.`login`, `User`.`id`, Project.id 
FROM `authake_users` AS `User` 
LEFT JOIN `applicants` AS `Applicant` 
    ON `Applicant`.`authake_user_id` = `User`.`id` 
LEFT JOIN `projects` AS `Project` 
    ON `Project`.`applicant_id` = `Applicant`.`id` 
WHERE `User`.`login` LIKE _latin1 '%1000%' AND `Project`.`id` IS NULL; 

Ihre Anfrage im Auftrag von JOINS Wechsel - 2

SELECT `Applicant`.`id`, `Applicant`.`name`, `User`.`login`, `User`.`id`, Project.id 
FROM `projects` AS `Project` 
LEFT JOIN `applicants` AS `Applicant` 
    ON `Project`.`applicant_id` = `Applicant`.`id` 
LEFT JOIN `authake_users` AS `User` 
    ON `Applicant`.`authake_user_id` = `User`.`id` 
WHERE `User`.`login` LIKE _latin1 '%1000%' AND `Project`.`id` IS NULL; 

Plus, wenn Sie profitieren von Indizes vollständig solche Art von User.login LIKE _latin1 '%1000%' Bedingungen sollten vermieden werden erhalten möchten. Besser, etwas wie dieses zu verwenden, wenn Sie es wirklich benötigen User.login LIKE _latin1 '1000%'.

Ich wäre sehr interessiert, wenn Sie auch die EXPLAIN der Abfragen, die ich vorgeschlagen habe, posten könnte.

+0

Vielen Dank, wirklich die "wechselnde Reihenfolge der JOINS - 1" Lösung befestigen Sie die Abfrage deutlich –

+0

Cool! Und es wird noch besser, wenn Sie ihre EXPLAIN-Details ebenfalls teilen können :) –