2016-12-15 7 views
0

Welche der folgenden Abfragen Stil ist besser für die Leistung?MySQL-Leistung - LINKE JOIN/HAVING vs Sub-Abfrage

Grundsätzlich gebe ich viele verwandte Datensätze in eine Zeile mit GROUP_CONCAT zurück und ich muss nach einem anderen Join auf den GROUP_CONCAT-Wert filtern, und ich muss viele Joins/group_concats/havings oder Unterabfragen in der Reihenfolge hinzufügen um mehr verwandte Werte zu filtern. Ich sah, dass, offiziell, LINKER JOIN war schneller, aber ich frage mich, ob die GROUP_CONCAT und HAVING durch diese off.

(Dies ist ein sehr vereinfachtes Beispiel, die tatsächlichen Daten haben viele weiteren Attribute und es ist von einer Drupal MySQL Architektur lesen)

Dank!

Main Records 
+----+-----------------+----------------+-----------+-----------+ 
| id | other_record_id | value   | type  | attribute | 
+----+-----------------+----------------+-----------+-----------+ 
| 1 |    0 | Red Building | building |   | 
| 2 |    1 | ACME Plumbing | attribute | company | 
| 3 |    1 | east_side  | attribute | location | 
| 4 |    0 | Green Building | building |   | 
| 5 |    4 | AJAX Heating | attribute | company | 
| 6 |    4 | west_side  | attribute | location | 
| 7 |    0 | Blue Building | building |   | 
| 8 |    7 | ZZZ Mattresses | attribute | company | 
| 9 |    7 | south_side  | attribute | location | 
+----+-----------------+----------------+-----------+-----------+ 

location_transaltions 
+-------------+------------+ 
| location_id | value  | 
+-------------+------------+ 
|   1 | east_side | 
|   2 | west_side | 
|   3 | south_side | 
+-------------+------------+ 

locations 
+----+--------------------+ 
| id | name    | 
+----+--------------------+ 
| 1 | Arts District  | 
| 2 | Warehouse District | 
| 3 | Suburb    | 
+----+--------------------+ 

Abfrage # 1

SELECT 
    a.id, 
    GROUP_CONCAT(
     IF(b.attribute = 'company', b.value, NULL) 
    ) AS company_value, 
    GROUP_CONCAT(
     IF(b.attribute = 'location', b.value, NULL) 
    ) AS location_value, 
    GROUP_CONCAT(
     IF(b.attribute = 'location', lt.location_id, NULL) 
    ) AS location_id  
FROM 
records a 
LEFT JOIN records b ON b.other_record_id = a.id AND b.type = 'attribute' 
LEFT JOIN location_translations lt ON lt.value = b.value 
WHERE a.type = 'building' 
GROUP BY a.id 
HAVING location_id = 2 

Abfrage # 2

SELECT temp.* FROM (
    SELECT 
     a.id, 
     GROUP_CONCAT(
      IF(b.attribute = 'company', b.value, NULL) 
     ) AS company_value, 
     GROUP_CONCAT(
      IF(b.attribute = 'location', b.value, NULL) 
     ) AS location_value 
    FROM 
    records a 
    LEFT JOIN records b ON b.other_record_id = a.id AND b.type = 'attribute' 
    WHERE a.type = 'building' 
    GROUP BY a.id 
) as temp 
LEFT JOIN location_translations lt ON lt.value = temp.location_value 
WHERE location_id = 2 

Antwort

0

JOIN Verwendung ist in den meisten Fällen bevorzugt, da es Optimierer, welche Indizes zu verstehen, hilft er verwenden kann, um. In Ihrem Fall sieht Abfrage Nr. 1 gut genug aus.
Natürlich funktioniert es nur, wenn Tabellen Indizes hat. Prüftabelle records hat Indizes auf id, other_record_id, value und type Spalten, Tabelle location_translations auf value