2010-12-08 9 views
0

Je suis en sérieuse difficulté, j'ai une énorme requête subtile qui prend énormément de temps à s'exécuter. En fait, il gèle l'accès et parfois je dois tuer la requête ressemble à:Sélectionnez l'optimisation dans Access

SELECT 
    ITEM.*, 
    ERA.*, 
    ORDR.*, 
ITEM.COnTY1, 
(SELECT TOP 1 New FROM MAPPING WHERE Old = ITEM.COnTY1) AS NewConTy1, 
ITEM.COnValue1, 
(SELECT TOP 1 KBETR FROM GEN_KUMV WHERE KNUMV = ERA.DOCCOND AND KSCHL = (SELECT TOP 1  New FROM MAPPING WHERE Old = ITEM.COnTY1)) AS NewCOnValue1 
--... etc: this continues until ConTy40 

FROM 
GEN_ITEMS AS ITEM, 
GEN_ORDERS AS ORDR, 
GEN_ERASALES AS ERA 

WHERE 
ORDR.ORDER_NUM = ITEM.ORDER_NUM AND -- link between ITEM and ORDR 
ERA.concat = ITEM.concat -- link between ERA and ITEM 

Je ne vais pas vous fournir le schéma des tables depuis la requête fonctionne, ce que je voudrais savoir est s'il y a un moyen ajouter NewConTy1 et NewConValue1 en utilisant une autre technique pour le rendre plus efficace. Le fait est que les champs Con * vont de 1 à 40, donc je dois les aligner (NewConTy1 à côté de ConTy1 avec NewConValue1 à côté de nouveau ConValue2 ... etc jusqu'à 40). Conty # et ConTyValue # sont en éléments (chacun dans un champ) NewConty # et NewConValue # sont ERA (chacun dans un enregistrement)

J'espère vraiment que mon explication est assez pour comprendre mon problème, au plaisir de vous entendre les gars

EDIT:

Ignore le TOP 1 dans les CHOISIT, c'est parce que les décharges actuelles de données dont je dispose ne sont pas exactes, il va être enlevé plus tard

EDIT 2:

Une autre chose que ma requête retourne jusqu'à 230 champs aussi lol

Merci Miloud

+0

Le problème est la mauvaise structure de données. Corrigez cela et le problème (et les solutions de contournement requises) disparaissent. –

+0

@ David-W-Fenton Vous n'avez peut-être pas eu l'occasion de lire les commentaires? – Fionnuala

+0

Quels commentaires? Je ne vois rien pour résoudre les très graves problèmes structurels évidents dans le SQL. –

Répondre

3

Avez-vous envisagé une requête syndicale pour normaliser les éléments?

SELECT "ConTy1" As CTName, Conty1 As CTVal, 
     "ConTyValue1" As CTVName, ConTyValue1" As CTVVal 
     FROM ITEMS 
UNION ALL 
SELECT "ConTy2" As CTName, Conty2 As CTVal, 
     "ConTyValue2" As CTVName, ConTyValue2" As CTVVal 
     FROM ITEMS 
<...> 
UNION ALL 
SELECT "ConTy40" As CTName, Conty40 As CTVal, 
     "ConTyValue40" As CTVName, ConTyValue40" As CTVVal 
     FROM ITEMS 

Cela peut être une requête distincte qui relie à votre requête principale, ou une sous requête de votre requête principale, si cela est plus pratique. Il devrait alors être assez facile de dessiner la relation avec NewConty # et NewConValue # dans ERA.

+0

Remou, vous rock mon monde bébé garçon! Merci beaucoup, à cause de votre indice, j'ai divisé le temps d'exécution par 1000! Maintenant, je reçois des résultats en moins d'une minute! – CoolStraw

0

La réponse de Remou donne ce que vous voulez: une approche sensiblement différente. Cela fait un moment que je l'ai touché à l'optimisation des requêtes MS Access, et avait oublié les détails de son planificateur, mais vous pourriez vouloir essayer une suggestion trivial de faire réellement votre

WHERE conditions 

dans

INNER JOIN ON conditions 

Vous lancez des sous-requêtes corrélées 40ish donc ce qui précède ne vous aidera probablement pas (encore une fois la réponse de Remou adopte une approche différente et vous pouvez voir des améliorations réelles), mais laissez-nous savoir.

Une autre approche que vous pouvez prendre est de matérialiser une pièce coûteuse et de prendre l'idée de Remou, mais diviser en différentes parties où vous pouvez vous joindre directement. Par exemple, votre première sous-requête est corrélée sur ITEM.COnTY1, la seconde est corrélée sur ERA.DOCCOND et ITEM.ConTY1Si vous classifiez vos sous-requêtes selon des clés corrélées, vous pouvez les enregistrer en tant que requêtes (ou les matérialiser en tant que requêtes de table) et les joindre (ou les tables nouvellement créées), ce qui devrait être beaucoup plus rapide (et le cas des tables fonctionnera beaucoup plus vite, au détriment de la matérialisation - vous devrez donc exécuter quelques requêtes avant d'obtenir les dernières données - ceci peut être encapsulé dans une macro ou une fonction/sous-programme VBA).

Sinon (par exemple, si vous exécutez régulièrement la requête ci-dessus dans le cadre de votre cas d'utilisation professionnel normal) - reconcevoir votre base de données.

+0

Unreason merci pour vos conseils aussi et en effet Remou a souligné la bonne direction. Et bien c'est une base de données à utiliser dans les affaires courantes à des fins de test, les données d'entrée sont des fichiers de vidage donc pas moyen de recréer la base de données ou quelque chose (aussi à cause du calendrier) mais maintenant ça devrait fonctionner correctement. – CoolStraw

+0

Vous êtes les bienvenus. Juste une note - si votre entrée est des fichiers de vidage (ce qui n'est pas très précis), alors vous avez probablement toutes les chances de remodeler les choses .. :) Si c'est une contrainte de temps/fonctionne assez bien alors aucune objection :) – Unreason