none
Performance SQL Server RRS feed

  • Discussion générale

  • Bonjour,

     

    Lorsque je lance une requete en direct sous SQL mon temps de réponse est de 10s environ.

    WITH D_DICT AS (SELECT ID_DOSSIER, ID_DIRECTION, ID_DICT AS ID_DEMANDE,
    ID_RECEPISSE AS id_recepisse, REF_DECLARANT
                  FROM         DOSSIER_DICT
                  WHERE   (ID_DICT = 'CN20001000291'
                             OR 'CN20001000291' IS NULL or id_recepisse = 'CN20001000291')),
    Z_DEMANDE AS
        (SELECT     ID_DOSSIER, ID_DIRECTION, ID_DEMANDE, id_recepisse, REF_DECLARANT
          FROM         D_DICT AS DICT_1
         )
        SELECT DISTINCT
                                DEMANDE_1.ID_DOSSIER, DEMANDE_1.ID_DEMANDE, DEMANDE_1.id_recepisse, DEMANDE_1.REF_DECLARANT
         FROM         Z_DEMANDE AS DEMANDE_1 LEFT OUTER JOIN
                                VOIE_DEMANDE ON DEMANDE_1.ID_DOSSIER = VOIE_DEMANDE.ID_DOSSIER LEFT OUTER JOIN
                                VISITE_CHANTIER ON DEMANDE_1.ID_DOSSIER = VISITE_CHANTIER.ID_DOSSIER
         GROUP BY DEMANDE_1.ID_DOSSIER, DEMANDE_1.ID_DEMANDE,
    DEMANDE_1.id_recepisse, DEMANDE_1.REF_DECLARANT

     

     

    Lorsque je lance la même requete avec un sp_execute, la meme requete mais plusieurs dizaine de minute.

    exec sp_executesql N'

    WITH D_DICT AS (SELECT ID_DOSSIER, ID_DIRECTION, ID_DICT AS ID_DEMANDE,
    ID_RECEPISSE AS id_recepisse, REF_DECLARANT
                  FROM         DOSSIER_DICT
                  WHERE   (ID_DICT = @RefDEMANDE
                             OR @RefDEMANDE IS NULL or id_recepisse = @RefDEMANDE)),
    Z_DEMANDE AS
        (SELECT     ID_DOSSIER, ID_DIRECTION, ID_DEMANDE, id_recepisse, REF_DECLARANT
          FROM         D_DICT AS DICT_1
         )
        SELECT DISTINCT
                                DEMANDE_1.ID_DOSSIER, DEMANDE_1.ID_DEMANDE, DEMANDE_1.id_recepisse, DEMANDE_1.REF_DECLARANT
         FROM         Z_DEMANDE AS DEMANDE_1 LEFT OUTER JOIN
                                VOIE_DEMANDE ON DEMANDE_1.ID_DOSSIER = VOIE_DEMANDE.ID_DOSSIER LEFT OUTER JOIN
                                VISITE_CHANTIER ON DEMANDE_1.ID_DOSSIER = VISITE_CHANTIER.ID_DOSSIER
         GROUP BY DEMANDE_1.ID_DOSSIER, DEMANDE_1.ID_DEMANDE, DEMANDE_1.id_recepisse, DEMANDE_1.REF_DECLARANT'
    ,N'@RefDEMANDE nvarchar(13)'
    ,@RefDEMANDE=N'CN20001000291'

     

    Est ce que quelqu un aurait une idée de la raison ?

    Sachant qu'a terme cette requete est lancé vi sp_execute car elle fait partie d'un rapport Reporting Services.

     

    D'avance merci

    jeudi 21 avril 2011 12:47

Toutes les réponses

  • Bonsoir,

    Quel sont les types de données pour les colonnes ID_DICT et id_recepisse ? Je soupconne que dans votre 2eme requete vous utilisez un mauvais type de données qui pourrait éventuellement provoquer un scan ou lieu d'une recherche d'index.

    Avez vous comparer les 2 plans d'exécutions pour voir ?

    ++ 


    MCDBA | MCITP SQL Server 2005 / SQL Server 2008 | LPI Linux 1
    jeudi 21 avril 2011 21:13
    Modérateur
  • C'est normal. Votre requête est mal conçue... dans le premier  cas :

    OR 'CN20001000291' IS NULL

    est ignoré et le OU éliminé. En effet SQL Server dipose d'un des meilleurs optimiseur et lors de l'algébrisation il constante que vous avez écrit du code inutile qu'il élimine.

    Dans le second cas, ou vous passez la variable, le OU persistera.

    Solution : faire un COALESCE préventif de votre variable avec une valeur impossible, par exemple chaine vide.

     

    A +



    Frédéric BROUARD, Spécialiste modélisation, SGBR relationnel, optimisation, langage SQL * * * Le site sur le langage SQL et les SGBD relationnels : http://sqlpro.developpez.com/ * * * Expert SQL Server http://www.sqlspot.com : audit, optimisation, tuning, formation * * * Le blog sur SQL / MS SQL Server http://blog.developpez.com/sqlpro * * * Enseignant CNAM PACA, ISEN Toulon, CESI/EXIA Aix En Provence
    vendredi 22 avril 2011 08:03
  • En sus vous effectuez un GROUP BY qui n'a strictement aucun intérêt. En effet aucun opérateur d'agrégation ne figure ni dans le select ni dans une clause HAVING... !

    Enfin si vous nous aviez donné la structure des tables de votre requête nous aurions pu vous conseiller sur la pose des index !

     

    A +


    Frédéric BROUARD, Spécialiste modélisation, SGBR relationnel, optimisation, langage SQL * * * Le site sur le langage SQL et les SGBD relationnels : http://sqlpro.developpez.com/ * * * Expert SQL Server http://www.sqlspot.com : audit, optimisation, tuning, formation * * * Le blog sur SQL / MS SQL Server http://blog.developpez.com/sqlpro * * * Enseignant CNAM PACA, ISEN Toulon, CESI/EXIA Aix En Provence
    vendredi 22 avril 2011 13:14
  • Bonjour, Vincent,

    Est-ce que les dernières explications de Mikedavem et SQLpro vous ont aidé à comprendre la source de votre problème ? Merci pour partager les résultats avec nous, afin que d'autres personnes avec le même problème puissent profiter de ces solutions.

    Cordialement,

    Cipri


    Suivez MSDN sur Twitter   Suivez MSDN sur Facebook


    Ciprian DUDUIALA, MSFT  
    •Nous vous prions de considérer que dans le cadre de ce forum on n’offre pas de support technique et aucune garantie de la part de Microsoft ne peut être offerte.

    mardi 26 avril 2011 06:58
  • Excuser moi pour la réponse tardive

     

    Le type de donnée est du nvarchar(16) .

     

    Je n'arrive pas à afficher le plan d'exécution via sp_execute, si vous avez la méthode je suis preneur.

    Par ailleurs la requete est en fait une extraction d'une requete beaucoup plus conséquent. C'est pour cela qu'il ya peut être des group by peu performant mais globalement j'estime qu on devrait avoir à peu près les mêmes résultats dans les 2 cas vu que la requete est la m^me, seul le mode d'appel change. Il y a des index posé sur les colonnes du where (ID_DICT et ID_RECEPISSE) Cordialement,
    vendredi 6 mai 2011 13:23
  • Je n'arrive pas à afficher le plan d'exécution via sp_execute, si vous avez la méthode je suis preneur.

     

    Regardez du côté des DMV sys.dm_exec_cached_plans, sys.dm_exec_query_plan et sys.dm_exec_sql_text :

    SELECT *
    FROM sys.dm_exec_cached_plans C
    CROSS APPLY sys.dm_exec_query_plan(C.plan_handle) AS QP
    CROSS APPLY sys.dm_exec_sql_text(C.plan_handle) AS QT
    WHERE QT.text LIKE '%...%'
    ++

    MCDBA | MCITP SQL Server 2005 / SQL Server 2008 | LPI Linux 1



    lundi 9 mai 2011 09:37
    Modérateur
  • J'ai testé le coalesce qui effectivement améliore les choses dans le cas présent du test sur le null si on a une valeur.

    Par contre si le paramètre passé est null alors cela ne retourne rien (logique vous me direz) mais le but est bien de renvoyer l'intégralité en cas de null

     

    J'ai également le même type de problème avec des tests à Chaine vide, y aurait il également une solution de contournement ?

    Je remets l'équivalent de la requete.

     

    exec sp_executesql N'
    WITH D_DICT AS (SELECT ID_DOSSIER, ID_DIRECTION, ID_DICT AS ID_DEMANDE,
    ID_RECEPISSE AS id_recepisse, REF_DECLARANT
                  FROM         DOSSIER_DICT
                  WHERE   (ID_DICT = @RefDEMANDE
                             OR @RefDEMANDE ='''' or id_recepisse = @RefDEMANDE)),
    Z_DEMANDE AS
        (SELECT     ID_DOSSIER, ID_DIRECTION, ID_DEMANDE, id_recepisse, REF_DECLARANT
          FROM         D_DICT AS DICT_1
         )
        SELECT DISTINCT
                                DEMANDE_1.ID_DOSSIER, DEMANDE_1.ID_DEMANDE, DEMANDE_1.id_recepisse, DEMANDE_1.REF_DECLARANT
         FROM         Z_DEMANDE AS DEMANDE_1 LEFT OUTER JOIN
                                VOIE_DEMANDE ON DEMANDE_1.ID_DOSSIER = VOIE_DEMANDE.ID_DOSSIER LEFT OUTER JOIN
                                VISITE_CHANTIER ON DEMANDE_1.ID_DOSSIER = VISITE_CHANTIER.ID_DOSSIER
         GROUP BY DEMANDE_1.ID_DOSSIER, DEMANDE_1.ID_DEMANDE, DEMANDE_1.id_recepisse, DEMANDE_1.REF_DECLARANT'
    ,N'@RefDEMANDE nvarchar(13)'
    ,@RefDEMANDE='CN20001000291'

     

     

    D'avance merci

     



    mardi 10 mai 2011 13:32