Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Optimieren von MySQL-Abfragen über hierarchische Daten hinweg

Ohne Zeit zum Testen aufzuwenden, haben Sie ein unvollständiges Beispiel bereitgestellt? Sie sollten auf jeden Fall eine Neuordnung versuchen von verbundenen Tischen. Die Explain-Ausgabe bietet einige Informationen, sagen wir, die Bestellung nach key_len sollte heuristisch am schnellsten sein. Die erste zu filternde Tabelle sollte als letzte aufgeführt werden, falls der Optimierer das nicht herausfinden kann, glaube ich.

Nehmen wir also an, die Reihenfolge „c, v, k, u“ ist die beste.

SELECT DISTINCT
  `v`.`key`,
  `u`.`val`
FROM
  `VertexDictionary`  AS `u`
  JOIN `SpecialKeys`       AS `k` ON (`k`.`x`, `k`.`key`) = (`u`.`x`, `u`.`key`)
  JOIN `VertexDictionary`  AS `v`
  JOIN `ConnectedVertices` AS `c` ON (`u`.`x`, `u`.`y`  ) = (`c`.`tail_x`, `c`.`tail_y`)
           AND (`v`.`x`, `v`.`y`  ) = (`c`.`head_x`, `c`.`head_y`)
WHERE
  `v`.`x` = X
;

'rows' würde die Reihenfolge 'c/u, k, v' vorschlagen, aber das hängt von den Daten ab:

SELECT DISTINCT
  `v`.`key`,
  `u`.`val`
FROM
  `VertexDictionary`  AS `u`
  JOIN `VertexDictionary`  AS `v`
  JOIN `SpecialKeys`       AS `k` ON (`k`.`x`, `k`.`key`) = (`u`.`x`, `u`.`key`)
  JOIN `ConnectedVertices` AS `c` ON (`u`.`x`, `u`.`y`  ) = (`c`.`tail_x`, `c`.`tail_y`)
                                 AND (`v`.`x`, `v`.`y`  ) = (`c`.`head_x`, `c`.`head_y`)
 WHERE
  `v`.`x` = X
;

Hoffe das hilft.

AKTUALISIEREN (Vermeidung der varchar-Verknüpfung):

SELECT DISTINCT
  `v`.`key`,
  `u`.`val`
FROM
       `ConnectedVertices` AS `c`
  JOIN `VertexDictionary`  AS `u` ON (`u`.`x`, `u`.`y`  ) = (`c`.`tail_x`, `c`.`tail_y`)
  JOIN `VertexDictionary`  AS `v` ON (`v`.`x`, `v`.`y`  ) = (`c`.`head_x`, `c`.`head_y`)
WHERE
  (`u`.`x`, `u`.`key`) IN (SELECT `k`.`x`, `k`.`key` FROM `SpecialKeys` AS `k`)
AND
  `v`.`x` = X
;