2010-12-01 16 views
1

si je lance cette requêtelignes estimées inattendues dans le plan d'exécution de requêtes (SQL Server 2000)

select user from largetable where largetable.user = 1155 

(noter que je suis l'interrogation utilisateur vient de le réduire à sa plus simple cas)

Et regardez le plan d'exécution, un index de recherche est prévu [largetable a un index sur l'utilisateur], et les lignes estimées est correct 29.

Mais si je

select user from largetable where largetable.user = (select user from users where externalid = 100) 

[avec le résultat de la sous-requête étant la valeur unique 1155 comme ci-dessus quand je le code dur]

L'optimiseur de requête estime 117 000 lignes dans le résultat. Il y a environ 6.000.000 lignes dans largetable, 1700 lignes dans les utilisateurs. Lorsque je lance la requête bien sûr, je récupère les 29 lignes correctes malgré les énormes lignes estimées.

J'ai mis à jour les statistiques avec FullScan sur les deux tables sur les indices relevent, et quand je regarde les statistiques, ils semblent être corrects.

Il convient de noter, pour un utilisateur donné, il n'y a pas plus de 3000 lignes largetable.

Alors, pourquoi le plan d'exécution estimé montrent un grand nombre de lignes estimées? L'optimiseur ne devrait-il pas savoir, d'après les statistiques, qu'il cherche un résultat comportant 29 lignes correspondantes, ou un MAXIMUM de 3 000 lignes même s'il ne connaît pas l'utilisateur qui sera sélectionné par la sous-requête? Pourquoi cette énorme estimation? Le problème est que cette estimation importante influence alors une autre jointure dans une requête plus importante pour faire une analyse au lieu d'une recherche. Si j'exécute la requête plus grande avec la sous-requête, cela prend 1min 40 secs. Si elle est exécutée avec le codage dur 1155, cela prend 2 secondes. Ceci est très inhabituel pour moi ...

Merci,

Chris

Répondre

0

Avez-vous essayé cela?

SELECT lt.user 
FROM Users u 
    INNER JOIN largeTable lt 
     ON u.User = lt.User 
WHERE u.externalId = 100 

S'il vous plaît voir ceci: subqueries-vs-joins

+1

Oui, et, réécrire en tant que jointure a le même problème! – Querylous

1

L'optimiseur fait de son mieux, mais les statistiques et les estimations de comptage de ligne n'aller si loin (comme vous voyez).

Je suppose que votre requête plus complexe ne peut pas facilement être réécrite comme une jointure sans sous-requête. Si cela peut être, vous devriez essayer cela en premier.

A défaut, il est temps pour vous d'utiliser vos connaissances supplémentaires sur la nature de vos données pour aider l'optimiseur avec hints. Plus précisément, regardez l'option forceseek dans les conseils index. Notez que cela peut être mauvais si vos données changent plus tard, alors soyez conscient.

+0

'forceseek' est 2008 seulement. Le PO est sur 2000. –

+0

Ah, je ne m'en suis pas rendu compte. J'ai migré en 2000 il y a un moment et je n'avais rien pour le tester. :(Merci – Donnie

+0

Donnie,.. Je reçois le même effet quand je réécris comme une jointure, je ne pense pas que SS 2000 a FORCESEEK, mais je vais vérifier ce .. – Querylous