Question

J'ai un problème étrange avec SQL Server 2000 et je ne vois pas pourquoi cela se produirait.

Il existe deux tables, une clé primaire combinée avec un index clusterisé, les deux clés ayant la même structure:

(VARCHAR(11), INT, DATETIME)   /* can't change this, so don't suggest I should */

Alors, les rejoindre comme ceci est assez facile:

SELECT t1.Foo, t2.Bar
FROM   table1 t1 INNER JOIN table2 t2 ON t1.VarcharKey = t2.VarcharKey
WHERE  t1.VarcharKey = 'Foo'

En regardant le plan d'exécution de la requête, je vois ceci:

  • Recherche d'index en cluster [db]. [dbo]. [table1]. [PK_table1] (48%)
  • Recherche d'index en cluster [db]. [dbo]. [table2]. [PK_table2] (51%)
  • Boucles imbriquées (jointure interne) (1%) Avertissement: PAS D'ABONNEMENT PRÉDICAT
  • Sélectionnez (0%)

Maintenant, si je fais cela (notez la chaîne NVARCHAR!):

SELECT t1.Foo, t2.Bar
FROM   table1 t1 INNER JOIN table2 t2 ON t1.VarcharKey = t2.VarcharKey
WHERE  t1.VarcharKey = N'Foo'

je reçois:

  • Analyse d'index en cluster [db]. [dbo]. [table1]. [PK_table1] (98%)
  • Recherche d'index en cluster [db]. [dbo]. [table2]. [PK_table2] (1%)
  • Boucles imbriquées (jointure interne) (1%) aucun avertissement ici
  • Sélectionnez (0%)

Ce comportement me laisse un peu perplexe.

  • Pourquoi existe-t-il un "NO JOIN PREDICATE"? attention, et pourquoi ça disparaît quand je change 'Foo' en N'Foo '? Mes colonnes de clé ne sont pas de type NVARCHAR, cela ne devrait donc pas faire de différence, ou le devrait-il?
  • La présence de cet avertissement a-t-elle des implications négatives ou puis-je l'ignorer?
  • Pourquoi passe-t-il d'une recherche d'index à une analyse d'index?

Quelques informations d’arrière-plan: La cardinalité de la table est ca. 25 000 enregistrements une table, ca. 12 000 enregistrements dans l'autre. Le niveau de compatibilité de la base de données est 80 (SQL Server 2000). Le classement par défaut est SQL_Latin1_General_CP1_CI_AS , si cela fait une différence.

Voici le contenu de @@ VERSION :

  

Microsoft SQL Server 2000 - 8.00.2273 (Intel X86) 7 mars 2008 22:19:58 Copyright (c) 1988-2003 Édition Entreprise Microsoft Corporation sur Windows NT 5.0 (Build 2195: Service Pack 4)

PS: Je suis au courant de KB322854 , mais ce n'est pas cela, évidemment.

Était-ce utile?

La solution

  

Pourquoi change-t-on d'une recherche d'index?   vers une analyse d'index?

C’est en grande partie une hypothèse, mais voici:

Dans le premier cas ('Foo'), MSSQL reconnaît que la valeur recherchée correspond parfaitement à la première partie de l'index sur t1 et utilise donc l'index pour rechercher un enregistrement dans t1 (Index Seek, éventuellement une recherche binaire). Ayant trouvé un enregistrement dans t1 qui a un index qui correspond parfaitement à t2, il peut utiliser cet index pour rechercher des enregistrements dans t2.

Dans le second cas (N'Foo '), MSSQL reconnaît qu’il n’a PAS une correspondance parfaite entre l’index et la valeur recherchée. Il ne peut donc pas utiliser l’index en tant qu’index, mais doit créer une table complète. balayage. Cependant, étant donné que l’index contient les informations nécessaires (sous une forme différente) et qu’il est plus petit que la table complète, il peut effectuer une analyse complète de l’index comme s’il s’agissait de la table (ceci est plus rapide que l’analyse de la table car moins de pages sont utilisées). doivent être lus pour le disque, mais il semble qu’il prenne environ 90 fois plus de temps que la recherche d’index)

Autres conseils

à partir de SqlServerCentral :

les requêtes peuvent avoir ce qui ressemble à une condition de jointure parfaitement formée. Mais lorsque vous examinez le plan de requête, un avertissement indiquant «Aucun joint de prédicat» s'affiche, indiquant que 2 des tables impliquées n'ont pas de prédicat (lorsqu'elles sont jointes). L'ajout d'une option (ordre forcé) à la requête génère un plan complètement différent et l'avertissement disparaît (dans certains cas). C'est comme ça que vous savez que c'est le problème. La plupart des requêtes que j'ai vues qui fonctionnent mieux sur SQL 2000 présentent ce problème. La mise à jour cumulative 4 vers le SP 2 est censée résoudre le problème.

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