Mesure de la Performance de la requête: coût de la requête "Plan D'exécution" par rapport au temps pris"

j'essaie de déterminer la performance relative de deux requêtes différentes et j'ai deux façons de mesurer ceci à ma disposition:

1. Exécutez les deux et chronométrez chaque requête

2. Exécuter les deux et obtenir "coût de requête" du plan d'exécution réelle

voici le code que j'exécute pour chronométrer les requêtes...

DBCC FREEPROCCACHE
GO
DBCC DROPCLEANBUFFERS
GO
DECLARE @start DATETIME SET @start = getDate()
EXEC test_1a
SELECT getDate() - @start AS Execution_Time
GO

DBCC FREEPROCCACHE
GO
DBCC DROPCLEANBUFFERS
GO
DECLARE @start DATETIME SET @start = getDate()
EXEC test_1b
SELECT getDate() - @start AS Execution_Time
GO

ce que j'obtiens est le suivant:

Stored_Proc     Execution_Time     Query Cost (Relative To Batch)

test_1a         1.673 seconds      17%
test_1b         1.033 seconds      83%

les résultats du le temps d'exécution contredit directement les résultats du coût de requête, mais j'ai de la difficulté à déterminer ce que "coût de requête" signifie réellement. Ma meilleure supposition est qu'il s'agit d'un agrégat de lit / écrit/ CPU_Time / etc, Donc je suppose que j'ai quelques questions:

  1. Existe-t-il une source de définition pour expliquer ce que cette mesure signifie?

  2. Ce que les autres "les Performances de la Requête" paramètres n'gens utilisent, et ce sont de leurs mérites?



Il peut être important de noter qu'il s'agit d'un serveur SQL de taille moyenne, qui exécute MS SQL Server 2005 sur MS Server 2003 Enterprise Edition avec plusieurs processeurs et plus de 100 utilisateurs concurrents.

EDIT:

après quelques soucis j'ai réussi à obtenir L'accès Profiler sur ce serveur SQL, et peut donner des informations supplémentaires (qui soutient le coût de requête étant lié au système Ressources, pas le temps d'exécution lui-même...)

Stored_Proc    CPU      Reads    Writes   Duration   

test_1a        1313     3975     93       1386
test_1b        2297     49839    93       1207

Impressionnant que la prise de plus de CPU avec BEAUCOUP plus de Lectures prend moins de temps :)

44
demandé sur Dustin Laine 2009-02-19 13:40:48

6 réponses

le profileur trace le met en perspective.

  • requête a: 1.3 sec CPU, 1.4 sec Durée
  • "151930920 de la Requête" B: 2.3 secondes CPU, 1.2 secondes de durée

la requête B utilise le parallélisme: CPU > durée eg la requête utilise 2 CPU, moyenne 1,15 secondes chaque

requête a n'est probablement pas: CPU < duration

ce qui explique le coût relatif au lot: 17% du prix de la plan de requête simple et non parallèle.

l'optimiseur réalise que la requête B est plus chère et bénéficiera du parallélisme, même si cela demande un effort supplémentaire.

rappelez-vous cependant, que la requête B utilise 100% de 2 CPU (donc 50% pour 4 CPU) pour une seconde ou plus. La requête a utilise 100% D'un CPU simple pendant 1,5 secondes.

Le pic pour la requête A est inférieure, à la charge de l'accroissement de la durée. Avec un seul utilisateur, qui s'en soucie? Avec 100, peut-être que cela fait une différence...

33
répondu gbn 2009-02-19 13:05:15
SET STATISTICS TIME ON

SELECT * 

FROM Production.ProductCostHistory
WHERE StandardCost < 500.00;

SET STATISTICS TIME OFF;

Et voir l'onglet message, il ressemblera à ceci:

SQL Server Execution Times:

   CPU time = 0 ms,  elapsed time = 10 ms.

(778 row(s) affected)

SQL Server parse and compile time: 

   CPU time = 0 ms, elapsed time = 0 ms.
11
répondu Aditya Acharya 2011-10-17 11:50:15

les résultats du temps d'exécution contredisent directement les résultats du coût de requête, mais j'ai de la difficulté à déterminer ce que" coût de requête " signifie réellement.

Query cost est ce que optimizer pense de la durée de votre requête (par rapport à la durée totale du lot).

L'optimiseur tente de choisir le plan de requête optimal en regardant votre requête et les statistiques de vos données, en essayant plusieurs plans d'exécution et choisir le moins coûteux d'entre eux.

Ici , vous pouvez lire plus en détail sur la façon qu'il ne tente de le faire.

comme vous pouvez le voir, cela peut différer considérablement de ce que vous obtenez réellement.

la seule vraie métrique de performance de requête est, bien sûr, combien de temps la requête prend réellement.

5
répondu Quassnoi 2009-02-19 10:59:43

Utiliser SET STATISTICS TIME ON

au-dessus de votre requête.

ci-dessous, près de l'onglet résultat, vous pouvez voir un onglet message. De là, vous pouvez voir l'heure.

3
répondu NMK 2011-10-17 11:49:31

je comprends que c'est une vieille question – je voudrais toutefois ajouter un exemple où le coût est le même, mais une requête est mieux que l'autre.

comme vous l'avez fait remarquer dans la question, le pourcentage indiqué dans le plan d'exécution n'est pas le seul critère pour déterminer la meilleure requête. Dans l'exemple suivant, j'ai deux requêtes à faire la même tâche. Plan d'exécution montre que les deux sont également bons (50% chacun). Maintenant j'ai exécuté les requêtes avec SET STATISTICS IO ON qui montre des différences claires.

dans l'exemple suivant, la requête 1 utilise seek tandis que la requête 2 utilise scan sur la table LWManifestOrderLineItems. Quand nous vérifions réellement le temps d'exécution cependant il est de trouver que la requête 2 fonctionne mieux.

lire aussi quand une recherche n'est-elle pas une recherche? de Paul White

REQUÊTE

---Preparation---------------
-----------------------------
DBCC FREEPROCCACHE
GO
DBCC DROPCLEANBUFFERS
GO

SET STATISTICS IO ON  --IO
SET STATISTICS TIME ON

--------Queries---------------
------------------------------

SELECT LW.Manifest,LW.OrderID,COUNT(DISTINCT LineItemID)
FROM LWManifestOrderLineItems LW
INNER JOIN ManifestContainers MC
    ON MC.Manifest = LW.Manifest
GROUP BY LW.Manifest,LW.OrderID
ORDER BY COUNT(DISTINCT LineItemID) DESC  

SELECT LW.Manifest,LW.OrderID,COUNT( LineItemID) LineCount
FROM LWManifestOrderLineItems LW
WHERE LW.Manifest IN (SELECT Manifest FROM ManifestContainers)
GROUP BY LW.Manifest,LW.OrderID
ORDER BY COUNT( LineItemID) DESC  

statistiques IO

enter image description here

Plan D'Exécution

enter image description here

2
répondu Lijo 2016-03-02 21:30:09

Exécution De La Requête Du Temps:

DECLARE @EndTime datetime
DECLARE @StartTime datetime 
SELECT @StartTime=GETDATE() 


` -- Write Your Query`

SELECT @EndTime=GETDATE()
--This will return execution time of your query
SELECT DATEDIFF(MILLISECOND,@StartTime,@EndTime) AS [Duration in millisecs] 

Requête de Sortie Sera Comme:

enter image description here

Pour Optimiser Le Coût D'Interrogation:

cliquez sur votre Studio de gestion SQL

enter image description here

lancez votre requête et cliquez sur plan D'exécution à côté de L'onglet Messages de votre résultat de requête. vous verrez comme

enter image description here

0
répondu atik sarker 2014-01-14 15:02:48