none
Performance em Select com CTE RRS feed

  • Pergunta

  • Pessoal

        Estou em um projeto onde tenho um select onde o tempo de reposta ainda não está legal, conforme abaixo, como estou utilizando cte teria como fazer de outra forma que consegui-se um retorno melhor, onde no momento não podemos utilizar o columnstore index.

    with dados as
    (
    SELECT top 5 
    id_cliente,nm_cliente,nr_cep,data_insert
    from tb_cliente_201708 with (nolock) 
      where data_insert >= convert(datetime,'2018/04/01')
    )
    select *
    from dados
    order by data_insert desc
    


       

    quinta-feira, 18 de abril de 2019 14:54

Respostas

  • Deleted
    • Marcado como Resposta neibala sexta-feira, 3 de maio de 2019 02:44
    quarta-feira, 24 de abril de 2019 12:24
  • Neibala,

    Dentro de uma CTE você só terá a possibilidade de utilizar o comando Order By em conjunto com o comando TOP ou OffSet declarado na CTE.

    No seu caso, elabore a CTE conforme sugerido pelo José Diz, e adicione o Order By no momento de executar a CTE, ou seja, logo após o comando Select que faz a chamada da mesma.


    Pedro Antonio Galvão Junior [MVP | MCC | MSTC | MIE | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados Relacional e Data Warehouse | Professor Universitário | @JuniorGalvaoMVP | http://pedrogalvaojunior.wordpress.com]


    sexta-feira, 26 de abril de 2019 00:18

Todas as Respostas

  • Deleted
    quinta-feira, 18 de abril de 2019 15:14
  • Neibala,

    Não existe uma receita de bolo, manual ou guia de boas práticas padrão que pode ser seguido para se afirmar o que esta lento ou não.

    Existem muitos, mais muitos cenários tanto relacionados a Hardware, como também, a Software ou propriamente a aplicação. 

    Um dos elementos que gusto de analisar de cara é a query que esta sendo supostamente executada, e através dela, começar a mapear os elementos envolvidos no processamento.

    Agora um ponto de muito importância, quando utilizamos conversão explícita na claúsula Where, o SQL Server é obrigado a internamente ter que alterar toda lógica predefinida de processamento da query, ou seja, torna-se necessário aplicar em alguns casos um novo plano de execução.

    Pergunto, você realmente precisa realizar a conversão dos dados no Where?


    Pedro Antonio Galvão Junior [MVP | MCC | MSTC | MIE | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados Relacional e Data Warehouse | Professor Universitário | @JuniorGalvaoMVP | http://pedrogalvaojunior.wordpress.com]



    quinta-feira, 18 de abril de 2019 22:23
  • Deleted
    sexta-feira, 19 de abril de 2019 09:17
  • Pessoal / José Diz / Junior

        Os assuntos relatados por você foram muito bem informando onde tinha visto anteriormente em outros assuntos relacionados a questão de performance e me ajudou a relembrar e até mesmo a verificar que estava trabalhando dentro do esperado, agora a sua informação abaixo, na questão da escolha, fiquei com dúvida então se eu utilizar a opção 103 seria a melhor opção do que a 111, mais isto estaria relacionado a algo do banco de dados ou a algo de padrão do formato data ?

    Sugiro que substitua 
       convert(datetime,'2018/04/01')
    por 
      convert(datetime, '2018/04/01', 111)      -- aaaa/mm/dd
    ou, melhor ainda, por
      convert(datetime, '1/4/2018', 103')         -- dd/mm/aaaa

    segunda-feira, 22 de abril de 2019 01:52
  • Agora um ponto de muito importância, quando utilizamos conversão explícita na claúsula Where, o SQL Server é obrigado a internamente ter que alterar toda lógica predefinida de processamento da query, ou seja, torna-se necessário aplicar um novo plano de execução.

    Pedro, a utilização de conversão de tipo de dado (seja implícita ou explícita) na cláusula WHERE somente afeta (ou não) o plano de execução caso torne o predicado non sargable.

    Construções do tipo
       (a) where função (coluna) operador ...
    podem tornar o predicado non sargable. Mas com relação a construções do tipo
       (b) where coluna operador função (constante)
    não se pode afirmar de antemão que torne o predicado non sargable.

    No caso do código de "neibala",
       where data_insert >= convert(datetime,'2018/04/01')
    observa-se que a coluna data_insert não está envolta por função. Ou seja, é o caso (b). Então, a conversão explícita em si,
       convert(datetime,'2018/04/01')
    não torna o predicado non sargable de antemão. O único cuidado que "neibala" deve tomar, neste caso em específico, é que os tipos de dados sejam os mesmos. Se a coluna data_insert estiver declarada como datetime, então o predicado
       data_insert >= convert(datetime,'2018/04/01')
    é sargable.

    Considerando-se performance, uma boa prática é garantir que os predicados sejam sargable. Isto vale tanto para a cláusula WHERE quanto para a cláusula FROM/ON. Há um ótimo artigo sobre o assunto, Construindo códigos T-SQL eficientes: Sargability, que trata justamente de como garantir que os predicados sejam sargable. Inclusive o artigo contém técnicas de como transformar predicados non sargable em sargable. Recomendo a leitura para quem tenha interesse em compreender o assunto sargability.

    Mas mesmo o predicado sendo sargable, ainda assim não significa que o plano de execução seja otimizado. É que se não houver índice de cobertura pela coluna data_insert, já estaria a ocorrer leitura sequencial em toda a tabela (se heap) ou índice (se btree).



    José Diz     Belo Horizonte, MG - Brasil     [T-SQL performance tuning: Porto SQL]   [e-mail]


    Este conteúdo é fornecido sem garantias de qualquer tipo, seja expressa ou implícita.

    José,

    Ok, compreendo, mas o que eu quiz dizer é que o plano de execução ou melhor toda estratégia de execução da query será repensada, foi isso que eu quiz dizer, mas parece que não foi isso que você interpretou.

    Eu vou reforçar o que já destaquei, não gosto de utilizar conversão de dados no Where, independente do formato ou tipo de dados, isso eu procuro evitar ao máximo e ressalto para meus alunos.


    Pedro Antonio Galvão Junior [MVP | MCC | MSTC | MIE | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados Relacional e Data Warehouse | Professor Universitário | @JuniorGalvaoMVP | http://pedrogalvaojunior.wordpress.com]






    segunda-feira, 22 de abril de 2019 12:57
  • Junior

         Neste caso o que você me indicaria seria algo que o José Diz tinha comentado em outros post sobre utilizar algo como uma função ao invés de uma conversão de dados, seria algo +/- neste sentido, pois assim força a utilização do índice na busca dos dados e performance no processo ?

    quarta-feira, 24 de abril de 2019 01:40
  • Deleted
    • Marcado como Resposta neibala sexta-feira, 3 de maio de 2019 02:44
    quarta-feira, 24 de abril de 2019 12:24
  • Grupo / José Diz

         Na questão da data deu para entender, agora na questão do order by a estrutura que passei estaria dentro do padrão de um processo normal ou se eu colocar o order by dentro da seleção do cte, isto utilizando o comando adequado ele por algum motivo pode ter algum ganho em relação ter colocado fora ou isto não interfere na estrutura, isto com base no seu conhecimento independente da questão de analisar o ambiente, pois isto serviria para eu ter a ideia da estrutura do cte.

          

    quinta-feira, 25 de abril de 2019 20:04
  • Neibala,

    Dentro de uma CTE você só terá a possibilidade de utilizar o comando Order By em conjunto com o comando TOP ou OffSet declarado na CTE.

    No seu caso, elabore a CTE conforme sugerido pelo José Diz, e adicione o Order By no momento de executar a CTE, ou seja, logo após o comando Select que faz a chamada da mesma.


    Pedro Antonio Galvão Junior [MVP | MCC | MSTC | MIE | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados Relacional e Data Warehouse | Professor Universitário | @JuniorGalvaoMVP | http://pedrogalvaojunior.wordpress.com]


    sexta-feira, 26 de abril de 2019 00:18
  • Junior / José Diz

          Obrigado pelas informações.

    sexta-feira, 3 de maio de 2019 02:44