Question

J'ai une table dans ma base de données représentant un arbre. Les données sont stockées en utilisant ensembles imbriqués . Je veux écrire une requête pour rechercher l'arbre et retourner seulement les noeuds qui correspondent à un modèle, ainsi que leurs ascendants et descendants. Voilà ce que je suis venu avec à ce jour.

SELECT DISTINCT Node, Parent, Description
FROM Hierarchy 
INNER JOIN 
    (SELECT Lft, Rgt 
    FROM Hierarchy 
    WHERE Description LIKE '%SEARCHQUERY%') AS Matches 
ON (Hierarchy.Lft <= Matches.Lft AND 
    Hierarchy.Rgt >= Matches.Rgt) OR 
    (Hierarchy.Lft >= Matches.Lft AND 
    Hierarchy.Rgt <= Matches.Rgt) 
ORDER BY Description

Cette requête fonctionne, mais il est un peu lent lorsque la sous-requête correspond à beaucoup de descriptions. Je cherche des idées sur la façon d'améliorer les performances de cette requête.

Dans le cas où il est pertinent, j'utilise Access.

Je suis libre et prêt à changer la structure de la table pour améliorer cette requête. Le tableau a environ 8000 nœuds. Le nombre d'enregistrements ne changera pas beaucoup par la durée de vie de l'application. La profondeur maximale est de cinq.

La performance est acceptable pour des recherches régulières (quelques secondes pour les recherches qui retournent ~ 200 nœuds), mais sur des cas pathologiques, il faut quelques minutes (si la recherche d'une seule voyelle, par exemple. Mais même dans ces cas, la sous-requête prend moins d'une seconde à exécuter).

Était-ce utile?

La solution

Je me éloigne probablement un peu de la question initiale, mais ici, je vais:

Comme suggéré dans les commentaires, étant donné que vous pouvez vous permettre une ré-écriture, vous devez enquêter sur une autre façon de modéliser la structure de votre arbre, en particulier étant donné que vous avez une « profondeur fixe » qui est assez facile à gérer avec une approche différente.

Faroult dans son « L'art de SQL » privilégie une approche basée sur la représentation de la position du noeud dans un champ de chaîne codant pour la « branche » le noeud vit. (Pour un examen du livre, et un peu de discussion, voir ce fil Slashdot ).

Voici un exemple en ligne de ce que je veux dire - l'art de SQL a toute une section du livre dédié à cela, comparant trois approches différentes (structures hiérarchisées, parent / table relation enfant, champ de chemin encodée) et en utilisant l'ordre de bataille des armées à Waterloo comme un exemple (avec beaucoup de des requêtes telles que « Liste de tous les bataillons du général X » ou « Trouver qui était le commandant du groupe d'artillerie Y »).

Faroult est assez fanatique de la performance et l'ensemble du livre est une collection spécifique non vendeur de très bons conseils et pratiques sur la façon de (re) écrire des requêtes efficaces.

Autres conseils

Je serais probablement utiliser juste un champ parent_id dans le tableau, et d'utiliser une auto-jointure externe 3 voies pour obtenir les enregistrements hierarchy cible (filtrés de manière appropriée) ainsi que leurs parents (le cas échéant) et de l'enfant (le cas échéant) des documents .

La raison pour laquelle votre requête est lente est la partie LIKE('%blah%'). Si vous pouvez laisser tomber les premières choses % vont accélérer sensiblement. Ou, si Access prend en charge les indices FULLTEXT, puis mettre un sur le champ Description et faire MATCH(Description) AGAINST ('blah')

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top