2 votes

ACCESS 2000 : les requêtes "s'enchaînent" trop lentement avec l'ajout de la clause "WHERE".

PREMISE

Je dois modifier une très vieille base de données Access 2000. J'ai deux tables :

Produits table :

  • pID en tant que texte - Voici le champ clé (oui, c'est du texte, mais je ne peux rien y faire).
  • pLevel en tant que nombre entier - c'est le niveau du produit : 0=Fini, 1 à 7=Sous-produit
  • pDescription en tant que texte - Juste une description

P-Association table :

  • pIDParent comme Texte
  • pIDChild comme Texte

Ce tableau permet d'établir une association entre un (sous-)produit et un autre sous-produit. La "règle" est que le niveau pIDChild doit être supérieur au niveau pIDParent.

Ensuite, il y a un formulaire qui montre tous les enfants d'un pID donné. Ceci est basé sur une "chaîne" de requêtes :

Il s'agit de la requête q-pAssociation0, qui examine le produit sélectionné et renvoie les enfants :

SELECT DISTINCTROW [t-Associations].pIDParent, [t-Associations].pIDChild, [t-Products].pLevel AS pParentLevel, [t-Products].pLevel AS pChildLevel FROM [t-Products] INNER JOIN [t-Associations] ON [t-Products].pID = [t-Associations].pIDChild
WHERE ((([t-Associations].pIDParent)=[Forms]![fTreeProdotti]![txtProdID]));

puis il y a 7 requêtes (q-pAssociation1~q-pAssociation7) chacun travaillant sur le précédent. Voici le q-pAssociation1 :

SELECT DISTINCTROW [q-pAssociation0].pIDChild AS pIDParent, [t-Associations].pIDChild, [q-pAssociation0].pChildLevel AS pParentLevel, [t-Products].pLevel AS pChildLevel FROM [q-pAssociation0] INNER JOIN ([t-Products] INNER JOIN [t-Associations] ON [t-Products].pID = [t-Associations].pIDChild) ON [q-pAssociation0].pIDChild = [t-Associations].pIDParent;

A la fin, il y a une requête GROUP qui regroupe toutes les précédentes et sur laquelle le formulaire est basé.

QUESTION Je dois modifier tout cela pour que les requêtes ne renvoient que les enfants dont le niveau est égal au niveau du parent+1 (ainsi, si un parent a un enfant de 2 niveaux inférieurs ou plus, il n'est pas nécessaire de le renvoyer).

J'ai donc ajouté une condition dans chaque requête :

SELECT DISTINCTROW [q-pAssociation0].pIDChild AS pIDParent, [t-Associations].pIDChild, [q-pAssociation0].pChildLevel AS pParentLevel, [t-Products].pLevel AS pChildLevel
FROM [q-pAssociation0] INNER JOIN ([t-Products] INNER JOIN [t-Associations] ON [t-Products].pID = [t-Associations].pIDChild) ON [q-pAssociation0].pIDChild = [t-Associations].pIDParent
WHERE ((([t-Products].pLevel)=[q-pAssociation0]![pParentLevel]+1));

Mais maintenant, la q-pAssociation7 a besoin de 10 minutes pour retourner environ 15 enregistrements, alors que sans la condition "WHERE", elle retourne environ 25 enregistrements presque immédiatement.

Comment puis-je obtenir seulement le produit qui est juste un niveau en dessous sans avoir cette requête lente ?

1voto

Gord Thompson Points 30178

Peut-être cela pourrait-il vous aider si vous créiez une requête qui isole toutes les associations qui sont à un niveau de distance...

SELECT a.pIDParent, a.pIDChild, tP.pLevel AS pParentLevel, tC.pLevel AS pChildLevel
FROM ([t-Associations] AS a INNER JOIN [t-Products] AS tP ON a.pIDParent = tP.pID) 
    INNER JOIN [t-Products] AS tC ON a.pIDChild = tC.pID
WHERE (((tC.pLevel)=[tP].[pLevel]+1));

...enregistrez-la en tant que [q-one_level_down], puis utilisez-la dans vos requêtes afin de ne pas avoir à vous référer (explicitement) à la table des produits pour obtenir les niveaux.

Si vous faites cela, votre requête [q-pAssociation0] devient...

SELECT [q-one_level_down].pIDParent, [q-one_level_down].pIDChild, 
    [q-one_level_down].pParentLevel, [q-one_level_down].pChildLevel
FROM [q-one_level_down]
WHERE ((([q-one_level_down].pIDParent)=[Forms]![fTreeProdotti]![txtProdID]));

... et (je crois) votre requête [q-pAssociation1] se transforme en

SELECT [q-one_level_down].pIDParent, [q-one_level_down].pIDChild, 
    [q-one_level_down].pParentLevel, [q-one_level_down].pChildLevel
FROM [q-pAssociation0__NEW_] INNER JOIN [q-one_level_down] 
    ON ([q-pAssociation0__NEW_].pChildLevel = [q-one_level_down].pParentLevel) 
        AND ([q-pAssociation0__NEW_].pIDChild = [q-one_level_down].pIDParent);

Si cette approche vous donne les résultats souhaités mais que vous la trouvez toujours trop lente, alors le prochain raffinement serait d'utiliser une requête Append pour persister les résultats de [q-one_level_down] dans une table locale qui a les quatre colonnes indexées, puis de l'utiliser. (Dans ce cas, vous voudrez peut-être la nommer [lt-one_level_down] -- "lt" pour "local table" -- pour éviter toute confusion).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X