none
ajuda com query RRS feed

  • Discussão Geral

  • bom dia!

    tenho uma query que está demorando demais pra executar.. gostaria de ajuda pra melhorar a performance dela..

    SELECT  '-' as contato, ActivityPointer.ActivityId, ActivityPointer.Description, 
    ActivityPointer.RegardingObjectIdName, ActivityPointer.RegardingObjectId, 
    ActivityPointer.CreatedOn, ActivityPointer.Subject , 
    CASE WHEN ActivityPointer.Subject IS NULL THEN 
    CASE (ActivityPointer.ActivityTypeCode) 
    WHEN '4202' THEN 'Email' WHEN '4210' THEN 'Telefonema' WHEN '4212' THEN 'Tarefa' 
    WHEN '4204' THEN 'Fax' WHEN '4207' THEN 'Carta' WHEN '4207' THEN 'Resposta Campanha' 
    WHEN '4214' THEN 'Atividade de Serviço' WHEN '4201' THEN 'Compromisso' 
    END 
    ELSE 
    CASE (ActivityPointer.ActivityTypeCode) WHEN '4202' 
    THEN ActivityPointer.Subject +' - '+'Email' 
    WHEN '4210' THEN ActivityPointer.Subject +' - '+'Telefonema' 
    WHEN '4212' THEN ActivityPointer.Subject +' - '+'Tarefa' 
    WHEN '4204' THEN ActivityPointer.Subject +' - '+'Fax' 
    WHEN '4207' THEN ActivityPointer.Subject +' - '+'Carta' 
    WHEN '4207' THEN ActivityPointer.Subject +' - '+'Resposta Campanha' 
    WHEN '4214' THEN ActivityPointer.Subject +' - '+'Atividade de Serviço' 
    WHEN '4201' THEN ActivityPointer.Subject +' - '+'Compromisso' END END as assunto 
    FROM ActivityPointer 
    WHERE  (ActivityPointer.ActivityId not in 
                   (select email.activityid  from email 
                    inner join ActivityPointer on email.activityid = ActivityPointer.Activityid)
              ) 
    and  (ActivityPointer.ActivityId not in 
                (select phonecall.activityid  
                 from phonecall 
                 inner join ActivityPointer on phonecall.activityid = ActivityPointer.Activityid)
         ) 
    and (ActivityPointer.ActivityId not in 
                 (select letter.activityid  from letter  
                 inner join ActivityPointer on letter.activityid = ActivityPointer.Activityid)
        ) 
    

    • Tipo Alterado Giovani Cr sexta-feira, 8 de novembro de 2013 13:12
    quarta-feira, 30 de outubro de 2013 11:25

Todas as Respostas

  • Bom dia,

    Kyrla, experimente fazer um teste com o Where da seguinte forma:

    WHERE
        not exists 
            (select 1 from email where email.activityid = ActivityPointer.Activityid) and
        not exists 
            (select 1 from phonecall where phonecall.activityid = ActivityPointer.Activityid) and
        not exists 
            (select 1 from letter where letter.activityid = ActivityPointer.Activityid) 

    Espero que ajude.


    Assinatura: http://www.imoveisemexposicao.com.br

    quarta-feira, 30 de outubro de 2013 11:36
  • olá!

    demorando mais ou menos a mesma coisa.. uma coisa que eu fiz que ficou mais rápida, foi retirar esses subselects e colocar fora com left join, só que se deixo o que está comentado, ele altera o resultado da minha query.. 

    left join email on email.activityid = ActivityPointer.Activityid --AND email.activityid IS NULL
    left join phonecall on phonecall.activityid = ActivityPointer.Activityid --and  phonecall.activityid IS NULL
    left join letter on letter.activityid = ActivityPointer.Activityid --AND letter.activityid IS NULL
    
    se coloco o que está comentado no WHERE ele retorna o mesmo valor, mas continua demorando..
    quarta-feira, 30 de outubro de 2013 11:42
  • Talvez assim melhore:

    SELECT  '-' as contato, ActivityPointer.ActivityId, ActivityPointer.Description, 
    ActivityPointer.RegardingObjectIdName, ActivityPointer.RegardingObjectId, 
    ActivityPointer.CreatedOn, ActivityPointer.Subject , 
    CASE WHEN ActivityPointer.Subject IS NULL THEN 
    CASE (ActivityPointer.ActivityTypeCode) 
    WHEN '4202' THEN 'Email' WHEN '4210' THEN 'Telefonema' WHEN '4212' THEN 'Tarefa' 
    WHEN '4204' THEN 'Fax' WHEN '4207' THEN 'Carta' WHEN '4207' THEN 'Resposta Campanha' 
    WHEN '4214' THEN 'Atividade de Serviço' WHEN '4201' THEN 'Compromisso' 
    END 
    ELSE 
    CASE (ActivityPointer.ActivityTypeCode) WHEN '4202' 
    THEN ActivityPointer.Subject +' - '+'Email' 
    WHEN '4210' THEN ActivityPointer.Subject +' - '+'Telefonema' 
    WHEN '4212' THEN ActivityPointer.Subject +' - '+'Tarefa' 
    WHEN '4204' THEN ActivityPointer.Subject +' - '+'Fax' 
    WHEN '4207' THEN ActivityPointer.Subject +' - '+'Carta' 
    WHEN '4207' THEN ActivityPointer.Subject +' - '+'Resposta Campanha' 
    WHEN '4214' THEN ActivityPointer.Subject +' - '+'Atividade de Serviço' 
    WHEN '4201' THEN ActivityPointer.Subject +' - '+'Compromisso' END END as assunto 
    FROM ActivityPointer 
    LEFT JOIN email ON
    email.activityid = ActivityPointer.Activityid
    LEFT JOIN phonecall ON
    phonecall.activityid = ActivityPointer.Activityid
    LEFT JOIN letter  ON
    letter.activityid = ActivityPointer.Activityid
    WHERE  
    email.activityid IS NULL AND
    phonecall.activityid IS NULL AND
    letter.activityid IS NULL

    Não testei.

    Outro fato que você pode verificar é a ordem dos campos, se estiver seguindo um dos index dessa tabela ele ficará mais performático.


    "A vida é um paraíso, mas os homens não o sabem e não se preocupam em sabê-lo." Fiodor Dostoievski

    quarta-feira, 30 de outubro de 2013 11:46
  • left join email on email.activityid = ActivityPointer.Activityid 
    left join phonecall on phonecall.activityid = ActivityPointer.Activityid 
    left join letter on letter.activityid = ActivityPointer.Activityid 
    WHERE email.activityid IS NULL AND phonecall.activityid IS NULL AND letter.activityid IS NULL
    

    Tenta fazer desta forma, e vê se continua afetando o resultado

    quarta-feira, 30 de outubro de 2013 11:50
  • Kyrla, as tabelas Email, PhoneCall e Letter possuem uma Foreign Key referenciando a coluna ActivityId da tabela ActivityPointer?

    Assinatura: http://www.imoveisemexposicao.com.br

    quarta-feira, 30 de outubro de 2013 11:57
  • na verdade são todas views..
    quarta-feira, 30 de outubro de 2013 12:09
  • já fiz assim.. o resultado não altera, mas fica lento do mesmo jeito..
    quarta-feira, 30 de outubro de 2013 12:09
  • Provavelmente é por isso que está causando a lentidão.

    Verifique como estão criadas as consultas dessas views.
    Elas não devem estar bem montadas.


    "A vida é um paraíso, mas os homens não o sabem e não se preocupam em sabê-lo." Fiodor Dostoievski

    quarta-feira, 30 de outubro de 2013 12:15
  • Já verificou os índices, tem índices? fez o rebuild?
    quarta-feira, 30 de outubro de 2013 12:20
  • as views não tem indices..
    quarta-feira, 30 de outubro de 2013 12:45
  • Mas as tabelas utilizadas nas views sim.
    quarta-feira, 30 de outubro de 2013 12:52
  • Kyrla,

    Execute sua consulta com a opção "Display Estimated Execution Plan", como indicado na imagem abaixo

    Se houver necessidade de criar índices para esta consulta, o SQL Server vai indicar logo acima do retorno dos dados em verde. Clique com o botão direito do mouse.

    Espero que seja útil para você.

    Abraços,

    Durval Ramos
    Microsoft Partner | MTA - SQL Server 2012
    ----------------------------------
    Se foi resolvido clique "Marcar como resposta" e se foi útil "Votar como Útil"
    quarta-feira, 30 de outubro de 2013 13:17
    Moderador
  • o que ele me retornou antes de um monte de desenho foi:

    Query 1: query cost (relative to the batch) : 100%

    quarta-feira, 30 de outubro de 2013 13:41
  • Dê uma lida aqui e aqui.

    Deve te ajudar


    "A vida é um paraíso, mas os homens não o sabem e não se preocupam em sabê-lo." Fiodor Dostoievski

    quarta-feira, 30 de outubro de 2013 13:50
  • Kyrla,

    Não apareceu nenhum texto em verde com descrição da consulta ?

    Durval Ramos
    Microsoft Partner | MTA - SQL Server 2012
    ----------------------------------
    Se foi resolvido clique "Marcar como resposta" e se foi útil "Votar como Útil"

    quarta-feira, 30 de outubro de 2013 13:52
    Moderador
  • não..


    quarta-feira, 30 de outubro de 2013 14:04
  • Kirla,

    Ok, então tente executar esta proposta de alteração:

    SELECT '-' as contato, ACT.ActivityId, ACT.[Description],
    ACT.RegardingObjectIdName, ACT.RegardingObjectId, 
    ACT.CreatedOn, ACT.[Subject] ,
    COALESCE(ACT.[Subject], '') +' - '+ CASE (ACT.ActivityTypeCode)
    WHEN '4202' THEN 'Email'
    WHEN '4210' THEN 'Telefonema'
    WHEN '4212' THEN 'Tarefa'
    WHEN '4204' THEN 'Fax'
    WHEN '4207' THEN 'Carta'
    WHEN '4207' THEN 'Resposta Campanha'
    WHEN '4214' THEN 'Atividade de Serviço'
    WHEN '4201' THEN 'Compromisso'
    END AS assunto
    FROM ActivityPointer WITH(NOLOCK) AS ACT
    WHERE NOT EXISTS(select 1 from email WITH(NOLOCK) AS MAIL WHERE MAIL.activityid = ACT.Activityid) AND
    NOT EXISTS(select 1 from phonecall WITH(NOLOCK) AS PHO WHERE PHO.activityid = ACT.Activityid) AND
    NOT EXISTS(select 1 from letter WITH(NOLOCK) AS LET WHERE LET.activityid = ACT.Activityid) 

    Estou "executando" de cabeça ! Espero que funcione.

    Abraços,

    Durval Ramos
    Microsoft Partner | MTA - SQL Server 2012
    ----------------------------------
    Se foi resolvido clique "Marcar como resposta" e se foi útil "Votar como Útil"
    quarta-feira, 30 de outubro de 2013 14:22
    Moderador
  • 25 segundos.. mesma coisa.. =/

    mas obriagda

    quarta-feira, 30 de outubro de 2013 14:45
  • Kyrla, essas views utilizando tabelas certo?
    O script de geração dessas views está performático?
    Está obedecendo os índices das tabelas que ele utiliza?
    O ideal seria executar o plano de execução para cada uma das consultas das views para ver se existe alguma forma de melhorá-la.

    Outro ponto a ser observado é a quantidade de dados que essa consulta retorna.


    "A vida é um paraíso, mas os homens não o sabem e não se preocupam em sabê-lo." Fiodor Dostoievski

    quarta-feira, 30 de outubro de 2013 14:59
  • Kirla,

    Último teste, poderia criar estes índices abaixo:

    CREATE NONCLUSTERED INDEX [IX_ACTIVITY] ON [dbo].[email]
    (activityid ASC)
    WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 75) ON [PRIMARY]
    GO
    
    CREATE NONCLUSTERED INDEX [IX_ACTIVITY] ON [dbo].[phonecall]
    (activityid ASC)
    WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 75) ON [PRIMARY]
    GO
    
    CREATE NONCLUSTERED INDEX [IX_ACTIVITY] ON [dbo].[letter]
    (activityid ASC)
    WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 75) ON [PRIMARY]
    GO
    
    CREATE NONCLUSTERED INDEX [IX_ACTIVITY] ON [dbo].[ActivityPointer]
    (activityid ASC)
    INCLUDE ([Description],[RegardingObjectIdName],[RegardingObjectId],[CreatedOn],[Subject],[ActivityTypeCode])
    WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 75) ON [PRIMARY]
    GO

    Abraços,

    Durval Ramos
    Microsoft Partner | MTA - SQL Server 2012
    ----------------------------------
    Se foi resolvido clique "Marcar como resposta" e se foi útil "Votar como Útil"

    quarta-feira, 30 de outubro de 2013 15:48
    Moderador
  • Kirla,

    Faça o seguinte, remova os comandos Case e ao invês de utilizar o Where em conjunto com Exists, tenta fazer a junção através de Inner Join.

    Inicialmente parece-me que os cases estão forçando uma mudança no seu plano de execução.

    Você esta utilizando NoLock para evitar Locks, mas acho que no seu caso uma solução que poderia ajudar e forçar a escrita de um Minimal Logging seria utilizar o TabLock.


    Pedro Antonio Galvão Junior [MVP | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados | SorBR.Net | Professor Universitário | MSIT.com]

    sexta-feira, 1 de novembro de 2013 17:18