/ / Requête SQL prenant pour toujours - sql-server, datetime, join

Requête SQL prenant pour toujours - sql-server, datetime, join

J'ai cet outil d'application Web qui interroge des données et les affiche dans une grille. Maintenant, beaucoup de gens l'utilisent, il faut donc qu'il soit assez performant.

Le problème, c’est que j’avais besoin d’ajouter quelques champs supplémentaires par le biais de jointures et qu’il fallait maintenant énormément de temps pour que la requête soit exécutée.

Si je serveur SQL exécute la requête suivante:

select top 100 *
from bam_Prestatie_AllInstances p
join bam_Zending_AllRelationships r on p.ActivityID = r.ReferenceData
join bam_Zending_AllInstances z on r.ActivityID = z.ActivityID
where p.PrestatieZendingOntvangen >= "2010-01-26" and p.PrestatieZendingOntvangen < "2010-01-27"

Cela prend environ 35 à 55 secondes, ce qui est trop long. Parce que ce n'est qu'un petit.

Si je supprime l'une des deux vérifications de date, cela ne prend qu'une seconde. Si je supprime les deux jointures, cela ne prend que 1 seconde.

Lorsque j'utilise un plan de requête à ce sujet, je constate que 100% du temps est consacré à l'indexation du champ PrestatieZendingOntvangen. Si je règle ce champ pour être indexé, rien ne change.

Quelqu'un a une idée de ce qu'il faut faire?

Parce que mes clients commencent à se plaindre de time-outs, etc.

Merci

Réponses:

6 pour la réponse № 1

Outre la question évidente d’un index sur le bam_Prestatie_AllInstances.PrestatieZendingOntvangen colonne, vérifiez également si vous avez des index pour les colonnes de clé étrangère:

  • p.ActivityID (table: bam_Prestatie_AllInstances)
  • r.ReferenceData (table: bam_Zending_AllRelationships)
  • r.ActivityID (table: bam_Zending_AllRelationships)
  • z.ActivityID (table: bam_Zending_AllInstance)

L'indexation des champs de clé étrangère peut aider à accélérer un peu plus les JOINs sur ces champs!

En outre, comme cela a déjà été mentionné: essayez de limiter la sélection de vos champs en spécifiant une liste spécifique de champs, plutôt que d'utiliser SELECT * - surtout si vous rejoignez plusieurs tables, juste leLe simple nombre de colonnes que vous sélectionnez (multiplié par le nombre de lignes que vous sélectionnez) peut entraîner un transfert massif de données - et si vous n’avez pas besoin de toutes ces colonnes, c’est du gaspillage de bande passante!


2 pour la réponse № 2
  1. Spécifiez les champs que vous voulez récupérer plutôt que *
  2. Spécifiez une jointure interne ou externe

0 pour la réponse № 3

Essayez entre?

where p.PrestatieZendingOntvangen
between "2010-01-26 00:00:00" and "2010-01-27 23:00:00"

0 pour la réponse № 4

Avez-vous placé un index sur les champs de date dans votre Where clause.

Sinon, je créerais un index sur ces champs pour voir si cela fait une différence dans votre temps.

Bien sûr, les index occuperont plus d’espace disque, vous devrez donc prendre en compte l’impact de cet index supplémentaire.

MODIFIER:

Les autres ont également bien expliqué comment spécifier les colonnes dont vous avez besoin dans Select au lieu de * (caractère générique) et placer plus d'index sur les clés étrangères, etc.


0 pour la réponse № 5

Quelqu'un de fond de DB peut dissiper mon doute à ce sujet.

Je pense que vous devriez spécifier la date dans le style dans lequel la base de données pourra la comprendre.
par exemple En supposant que la date soit stockée dans le style mm / jj / aaaa à l'intérieur du tableau, votre requête essaye de mettre un style de date différent à des fins de comparaison (aaaa-mm-jj);

Suis-je trop naïf quand j'assume cela?


0 pour la réponse № 6

Combien de colonnes a bam_Prestatie_AllInstances et les autres tables? Il semblerait que vous remplissiez toutes les colonnes, ce qui peut poser un problème de performances.

Avez-vous essayé de sélectionner colonnes spécifiques à partir de tables spécifiques telles que:

select top 100 p.column1, p.column2, p.column3

Au lieu d'interroger toutes les colonnes comme vous le faites actuellement:

select top 100 *