Question

J'ai une procédure stockée qui ressemble à ceci (code pseudo)

  storedprocedure param1, param2, param3, param4
  begin
     if (param4 = 'Y')
         begin
             select * from SOME_VIEW order by somecolumn
         end
     else if (param1 is null)
          begin
             select * from SOME_VIEW
                where (param2 is null or param2 = SOME_VIEW.Somecolumn2)
                and (param3 is null or param3 = SOME_VIEW.SomeColumn3) 
             order by somecolumn
          end
     else
          select somethingcompletelydifferent
     end

Tout a bien fonctionné pendant longtemps. Soudain, la requête a commencé à courir pour toujours si param4 était « Y ». Modification du code à ceci:

  storedprocedure param1, param2, param3, param4
  begin
     if (param4 = 'Y')
         begin
             set param2 = null
             set param3 = null
         end
     if (param1 is null)
          begin
             select * from SOME_VIEW
                where (param2 is null or param2 = SOME_VIEW.Somecolumn2)
                and (param3 is null or param3 = SOME_VIEW.SomeColumn3) 
             order by somecolumn
          end
     else
          select somethingcompletelydifferent

Et il fonctionne à nouveau dans les paramètres attendus (15 secondes environ pour 40.000+ enregistrements). Ceci est avec SQL Server 2005. L'essentiel de ma question est cette « fonctionnalité » spécifique à SQL Server, ou est-ce une caractéristique commune SGBDR » en général que:

  1. Les requêtes qui RAN bien pour deux ans cesseront de fonctionner que les données se développe.
  2. Le « nouveau » plan d'exécution détruit la capacité du serveur de base de données pour exécuter la requête même si un parcours alternatifs logiquement équivalent très bien?

Cela peut sembler une diatribe contre SQL Server, et je suppose que dans une certaine mesure, il est, mais je ne veux vraiment savoir si d'autres éprouvent ce genre de réalité avec Oracle, DB2 ou tout autre SGBDR. Bien que j'ai une certaine expérience avec les autres, je ne l'ai vu ce genre de volume et la complexité sur SQL Server, donc je suis curieux de savoir si d'autres avec de grandes bases de données complexes ont une expérience similaire dans d'autres produits.

Était-ce utile?

La solution

Il pourrait y avoir deux ou trois causes

1) sont des statistiques à ce jour?

2) vous pourriez souffrir d'renifler paramètre

BTW pour ce genre de choses

où (param2 est nulle ou param2 = SOME_VIEW.Somecolumn2)

Jetez un oeil à Est-ce que vous utilisez la colonne = @param OU @param IS NULL dans la clause WHERE? Ne pas, il ne fonctionne pas

Autres conseils

J'imagine ce cas spécifique du problème, et toutes les conditions qui mènent à ce qui se passe sont spécifiques au serveur SQL - probablement même l'édition. (Par exemple SQL Server 2008 se comporte différemment.)

Mais ceci est une « caractéristique » générale des optimiseurs de requête. Ils regardent votre requête et essayer de faire une supposition éclairée quant à ce qui va exécuter le plus rapide. En tant qu'utilisateurs, nous avons peu de contrôle direct si les choisit optimiseur (par exemple) une analyse de l'indice ou un Index Seek, mais ils peuvent influencer indirectement en fournissant d'autres moyens d'exprimer la même chose, pour voir si cela invoque l'amélioration du temps d'exécution.

S'il n'y a pas eu d'autres changements de schéma qui pourraient influer sur la requête, puis vérifiez que les statistiques d'index sont mis à jour. Nous utilisons un traitement par lots par semaine pour le faire.

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