8
votes

Pourquoi cette déclaration SQL est-elle très lente?

J'ai une table avec environ 1 million d'enregistrements (exécutant SQL Server 2008 Web). J'ai une routine de recherche qui tente de faire correspondre le code de produit ainsi que la description du produit. Cependant, dans certaines circonstances, c'est très lent. Ci-dessous est (découper) SQL SMOND:

WITH AllProducts AS (
  SELECT       p.*, Row_Number() OVER (ORDER BY ProductId) AS RowNumber
  FROM        Product AS p 
    WHERE p.IsEnabled=1 AND
    (
      p.BaseSku = 'KPK-3020QWC-C' -- this on its own is fast
      OR
      CONTAINS(p.FreeTextStrings, '"KPK-3020QWC*"') -- and this on its own is fast, but not both
    )
) SELECT * FROM AllProducts        
  WHERE RowNumber BETWEEN 1 AND 20;


2 commentaires

Pouvez-vous nous montrer un plan d'exécution de votre serveur SQL?


Ces problèmes ont commencé à se produire après la mise à niveau de SQL 2005 sur SQL 2008.


3 Réponses :


13
votes

ou est notoirement lent sur SQL Server. C'est aggravant, de dire le moins.

Essayez de le diviser en deux requêtes avec un "code> Union : xxx


4 commentaires

Exactement, le "ou" est très probablement causant une balayage de table sur la table du produit, même s'il y a des index sur les basesku et les freeextstrings ... Un syndicat va tourner à l'indexer + l'analyse de l'index ... (en supposant qu'il y a des index couvrant des index. ces deux colonnes)


J'ai essayé cela et cela a en effet montré de grandes améliorations. Je vais essayer cette technique avec la déclaration complète SQL.


Oui, cela l'a résolu. Cependant, je pense qu'il est assez étrange que la même déclaration ait fonctionné très rapidement dans SQL 2005 et travaille lentement dans SQL 2008. Peut-être que cela serait traité dans le prochain service pack?


@MUXA: Ils ont apporté beaucoup d'améliorations avec le compilateur. ou la manipulation n'était pas l'un d'entre eux. Je suis avec toi, cependant. J'espère sincèrement que cela change bientôt!



1
votes

Cela semble bien fonctionner: xxx

(j'ai déjà eu basesku fts-indexé)


0 commentaires

0
votes

Assurez-vous que tous les index nécessaires sont en place. J'ai eu le même problème avec une clause ou dans l'une de mes requêtes et crée un index non clustered avec Inclure les colonnes fixées. performance.

après avoir des tests supplémentaires, il s'agissait de la partie inclure des colonnes de l'index qui corrigeait vraiment le problème de performance . Voici ce que j'ai fait pour déterminer le problème et comment le réparer:

Utilisez le plan d'exécution pour vous aider à créer les index manquants:

Sans l'index, la requête prenait 2+ min quand il aurait dû courir dans quelques millisecondes. J'ai donc comparé les plans d'exécution de la requête avec et sans la clause ou dans SSMS et il n'était pas évident ce que je devais faire (principalement en raison de mon manque de compréhension des plans d'exécution).

Mais si vous regardez au-dessus du plan d'exécution dans le texte vert, SSMS peut vous dire de créer un index non clustered. Hmm ... vaut un coup. J'ai donc créé l'index et le problème résolu! Vous pouvez cliquer avec le bouton droit sur la requête "Créer une index" et sélectionner "Détails d'index manquants ...". Cela ouvrira un nouvel onglet avec la requête complète pour que vous puissiez courir. Donnez-lui juste un nom.


0 commentaires