2010-11-30 8 views
2

Qu'est-ce qui rend une table sensiblement plus lente qu'une autre? Probablement plus facile pour illustrer simplement:Qu'est-ce qui rend une table "lente?"

Requête 1:

select top 1000 * 
from call c 
JOIN call_task ct ON c.call_no=ct.call_no 
LEFT JOIN memo_clt m ON m.doc_ref=ct.record AND m.doc_type='CLT' AND m.line_no=1 
LEFT JOIN memo_clt m2 ON m2.doc_ref=ct.record AND m2.doc_type='CLT' AND m2.line_no=2 

Requête 2:

select top 1000 * 
from call c 
LEFT JOIN ext_document_detail edd ON edd.doc_type='CLH' 
              AND edd.doc_ext_no=21 
              AND edd.doc_ref=c.record 
LEFT JOIN ext_document_detail edSource ON edSource.doc_type='CLH' 
               AND edSource.doc_ext_no=22 
               AND edSource.doc_ref=c.record 

La structure des tables est similaire, et je l'accès au ext_document_detail avec un très similaire rejoindre par rapport à la table memo_clt. Pourtant, la deuxième requête prend 40 secondes, tandis que l'autre prend 0 secondes.

Les deux ont un index cluster sur les trois clés que j'utilise pour la jointure. La table memo_clt a un index non clusterisé sur sa colonne record ... c'est la seule différence que je peux repérer et je ne pense pas que cela ferait une grande différence.

Alors pourquoi la différence de vitesse ici?

EDIT: Comme Martin a demandé, voici les résultats de SET STATISTIQUES IO Requête 1:

Table 'memo_clt'. Scan count 2000, logical reads 6454, physical reads 0, read-ahead reads 0, lob logical reads 2385, lob physical reads 0, lob read-ahead reads 0. 
Table 'call_task'. Scan count 1, logical reads 39, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. 
Table 'call'. Scan count 1, logical reads 25, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. 

Requête 2:

Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. 
Table 'ext_document_detail'. Scan count 1001, logical reads 1507004, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. 
Table 'call'. Scan count 1, logical reads 24, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. 

Dès le départ, deux choses me frappent. La première est qu'il n'y a pas de table telle que "Worktable". La seconde est le nombre absolument énorme de lectures logiques ... qu'est-ce qui causerait cela? Ce ne sont pas les tables elles-mêmes qui provoquent les différences de vitesse.

+0

À quoi ressemblent les plans d'exécution réels pour les deux? Que montre SET STATISTICS IO pour les deux? –

+0

RE: votre commentaire ** il n'y a pas de table comme "Table de travail". ** Je suppose qu'une jointure de hachage est dans le plan d'exécution réel? –

Répondre

2

Ce sont les structures des jointures et des index de support sur les tables interrogées. Pour vous donner une bonne raison de la différence de vitesse, j'ai besoin de voir votre plan d'exécution. Je soupçonne qu'une requête utilise mieux les index que les autres.

Un bon point de départ serait de voir si vous avez des balayages de table. Si vous les avez et que vous pouvez optimiser, vous verrez probablement une augmentation des performances.

Je donnerais une bonne lecture à this article. Il vaut certainement la peine de vérifier et de comprendre ..

+1

Deviner J'aurais dû regarder le plan d'exécution plus tôt ... j'ai remarqué qu'il y avait un prédicat convertissant implicitement doc_ref en un int. Ce qui m'a fait réaliser que le doc_ref est stocké en tant que varchar (50). Changement de la requête pour c.record en varchar et maintenant il s'exécute aussi vite que l'autre requête. Merci! – CodeRedick