Question

Je suis en train d'optimiser quelques requêtes SQL complexes car il effroyablement prend trop de temps pour terminer.

Dans mes requêtes, j'ai créé dynamiquement des instructions SQL avec beaucoup des mêmes fonctions, donc je crée une table temporaire où chaque fonction est appelée une seule fois au lieu de plusieurs, plusieurs fois - ce coupé mon temps d'exécution par 3/4.

Alors, ma question est, puis-je attendre à voir beaucoup de différence si disons, 1000 calculs de datediff sont rétrécies à 100?

EDIT: La requête ressemble à ceci:

SELECT DISTINCT M.MID, M.RE FROM #TEMP INNER JOIN M ON #TEMP.MID=M.MID 
WHERE ( #TEMP.Property1=1 ) AND 
DATEDIFF( year, M.DOB, @date2 ) >= 15  AND  DATEDIFF( year, M.DOB, @date2 ) <= 17 

lorsque celles-ci sont générées de façon dynamique en tant que chaînes (mis en place en morceaux) puis exécutée de telle sorte que différents paramètres peuvent être modifiés le long de chaque itération - principalement les dernières lignes, contenant toutes sortes de requêtes DATEDIFF

.

Il y a environ 420 requêtes comme celle-ci où ces datediffs sont calculés comme si. Je sais que je peux les tirer dans une table temporaire facilement (1000 datediffs devient 50) - mais est-ce la peine, ne fera aucune différence en quelques secondes? J'espère une amélioration meilleure que dans les dixièmes de secondes.

Était-ce utile?

La solution

Cela dépend exactement ce que vous faites pour être honnête dans la mesure du succès de la performance.

Par exemple, si vous utilisez DATEDIFF (ou tout autre fonction) dans une clause WHERE, alors ce sera une cause de moins bonnes performances, car elle empêche un index utilisé sur cette colonne.

par exemple. exemple de base, trouver tous les enregistrements en 2009

WHERE DATEDIFF(yyyy, DateColumn, '2009-01-01') = 0

ne serait pas faire bon usage d'un index sur DateColumn. Alors qu'une meilleure solution, fournissant une utilisation optimale de l'indice serait:

WHERE DateColumn >= '2009-01-01' AND DateColumn < '2010-01-01'

récemment blogué sur la différence cela fait (avec les statistiques de performance / comparaisons de plan d'exécution), si vous êtes intéressé.

Ce serait plus coûteux que de dire le retour DATEDIFF comme une colonne dans le resultset.

Je commencerais en identifiant les requêtes individuelles qui prennent le plus de temps. Vérifiez les plans d'exécution pour voir où est le problème et régler de là.

Edit: Sur la base de la requête par exemple que vous avez donné, voici une approche que vous pourriez essayer d'éliminer l'utilisation de DATEDIFF de la clause WHERE. exemple de base pour trouver tous ceux qui ont 10 ans à une date donnée - I pense les mathématiques est juste, mais vous avez l'idée de toute façon! Lui a donné un test rapide et semble très bien. Devrait être assez facile à adapter à votre scénario. Si vous voulez trouver des personnes entre (par exemple) 15 et 17 ans à une date donnée, c'est également possible avec cette approche.

-- Assuming @Date2 is set to the date at which you want to calculate someone's age 
DECLARE @AgeAtDate INTEGER
SET @AgeAtDate = 10  

DECLARE @BornFrom DATETIME
DECLARE @BornUntil DATETIME
SELECT @BornFrom = DATEADD(yyyy, -(@AgeAtDate + 1), @Date2)
SELECT @BornUntil = DATEADD(yyyy, -@AgeAtDate , @Date2)

SELECT DOB
FROM YourTable
WHERE DOB > @BornFrom AND DOB <= @BornUntil

Une note importante à ajouter, est pour caculates d'âge de la date de naissance, cette approche est plus précise. Votre implémentation actuelle ne prend que l'année de naissance en compte, et non le jour même (par exemple quelqu'un né le 1 décembre 2009 montrerait comme 1 an le 1 janvier 2010 quand ils ne sont pas 1 jusqu'au 1 décembre 2010).

Hope this helps.

Autres conseils

DATEDIFF est tout à fait efficace par rapport à d'autres méthodes de traitement des valeurs datetime, comme des chaînes. ( voir cette réponse SO ) .

Dans ce cas, il semble que vous ressasser les mêmes données, ce qui est probablement plus cher que d'utiliser une table temporaire. Par exemple, les statistiques seront générées.

Une chose que vous pourriez être en mesure faire pour améliorer la performance pourrait être de mettre un index sur la table temporaire sur MID.

Vérifiez votre plan d'exécution pour voir si elle aide (peut dépendre du nombre de lignes dans la table temporaire).

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