none
SQL timeout - Executando direto do SQL demora "0" segundos, mas na aplicacao, ta dando timeout, pq seria? RRS feed

  • Pergunta

  • Ola pessoal
    tenho uma consulta, onde me retorna 9.000 linhas, porem, ela em si no SQL demora "0" segundo(na chega  nem a marcar 1 segundo)
    dos dados que me retorna, tenho o seguinte
    [INT, VARCHAR(60),VARCHAR(20),INT]

    porem, qdo executo a mesma consulta na aplicacao, ela me retorna erro de "timeout"

    "corrigi" o erro da seguinte forma
    cmd.CommandTimeout = 0;
    porem, isso nao é o mais correto, ate pq nao entendo pq ela esta demorando tanto pra executar.
    essa demora toda seria pra transferir essas 9000 linhas pro reader?

    meu metado
            public List<Pessoa> selectInadimplenteLista(int inadimplenteDias, int umcId, String userName)
    
            {
    
                SqlConnection conn = new SqlConnection(GerenciadorConexao.StringConexao);
    
                SqlCommand cmd = new SqlCommand("SPClienteInadimplente", conn);
    
                cmd.CommandType = CommandType.StoredProcedure;
    
    
    
                SqlDataReader reader = null;
    
                List<Pessoa> pessoaLista = new List<Pessoa>();
    
    
    
                if (inadimplenteDias > 0  || umcId > 0)
    
                {
    
                    //cmd.CommandTimeout = 0;
    
                    cmd.Parameters.AddWithValue("@InadimplenteDias", inadimplenteDias);
    
                    cmd.Parameters.AddWithValue("@ContratoUMCID", umcId);
    
                    cmd.Parameters.AddWithValue("@UserName", Util.isNull(userName));
    
    
    
                    
    
                    conn.Open();
    
                    reader = cmd.ExecuteReader(CommandBehavior.CloseConnection);
    
    
    
                    while (reader.Read())
    
                    {
    
                        Pessoa pessoaTemp = new Pessoa();
    
                        pessoaTemp.Id = Convert.ToInt32(reader["ClienteId"]);
    
                        pessoaTemp.Nome = Convert.ToString(reader["ClienteNome"]);
    
                        pessoaTemp.Documento = Convert.ToString(reader["ClienteDocumento"]);
    
                        pessoaLista.Add(pessoaTemp);
    
                    }
    
                    conn.Close();
    
                }
    
    
    
                return pessoaLista;
    
            }
    minha classe de conexao

        public static class GerenciadorConexao
    
        {
    
            const String stringConexao = "server=192.168.0.1;uid=user;pwd=123456;database=DBTeste";
    
    
    
            public static String StringConexao
    
            {
    
                get { return stringConexao; }
    
            } 
    
    
    
    
    
        }
    postei o codigo dos metodos, pra ver se nao estou fazendo algo errado na hora de transferir do DB para o FRONT.

    abs
    T+

    É melhor acender uma vela do que praguejar contra e Escuridão
    • Editado Krusst quarta-feira, 8 de julho de 2009 20:08
    quarta-feira, 8 de julho de 2009 20:07

Respostas

  • Krusst,

    É bem provável que a demora no retorno do método está relacionado com a quantidade de registros (+- 9000).

    Algumas opções:

    1 - Utilizar um DataSet tipado e populá-lo por meio de um SqlDataAdapter (método Fill).
    http://msdn.microsoft.com/en-us/library/bh8kx08z(VS.85).aspx

    2 - Utilizar o Entity Framework.
    http://msdn.microsoft.com/en-us/library/aa697427(VS.80).aspx

    Att.

    Ari C. Raimundo
    sábado, 11 de julho de 2009 01:03
  • Krust,

    Conforme dito, você pode usar algumas ferramentas que fazem o mapeamento objeto relacional como DataSet Tipado ou EntityFrameWork, até a respeito do EF estou escrevendo muitas coisas legais dele no meu blog -> http://nelsonborgesjr.spaces.live.com/blog/

    A grande vantagem de se utilizar as ferramentas acima é que as mesmas incorporam uma série de padrões de código que ajudam minimizando o desenvolvimento e melhorando a performance e qualidade do código, uma vez que as mesmas são feitas em cima de design patterns. No entando nada impede você fazer na mão, mas no seu caso, se me permite posso dar algumas sugestões que podem melhorar ?:

    - Classe Gerenciador de Conexão
       - Deixe a string de conexão no config de sua aplicação de preferência criptografada. Veja -> http://www.dreamincode.net/code/snippet1676.htm
       - Se fizer o item acima não há necessidade de ter esta classe, pois poderá ler direto do config, detalhe que sua classe estatica poderá ter menos performance em ambientes multi-thread, então avalie o custo/beneficio.

    - Método selectInadimplenteLista
       -
    O Objeto SqlConnection implementa a interface IDispose, por isso você pode usar o using, exemplo: http://blog.dmbcllc.com/2008/11/10/dispose-with-using/
       - Se fizer o item acima não precisa do CommandBehavior.CloseConnection, pois o using irá controlar quando fechar a conexão, isso irá tirar mais um peso do DataReader.

    Lembre-se que performance não apenas sistema, verifique como esta seu banco de dados, Indices, Estatisticas na tabela, a configuração do servidor de banco, para isso pode usar o perfmon e o profile, se mesmo assim continuar ruim, você pode pensar em alguma solução de cache de dados -> http://www.devx.com/dotnet/Article/31158.


    Abraço,

    Nelson Borges - http://nelsonborgesjr.spaces.live.com/blog/
    quinta-feira, 16 de julho de 2009 03:41

Todas as Respostas

  • Krusst,

    É bem provável que a demora no retorno do método está relacionado com a quantidade de registros (+- 9000).

    Algumas opções:

    1 - Utilizar um DataSet tipado e populá-lo por meio de um SqlDataAdapter (método Fill).
    http://msdn.microsoft.com/en-us/library/bh8kx08z(VS.85).aspx

    2 - Utilizar o Entity Framework.
    http://msdn.microsoft.com/en-us/library/aa697427(VS.80).aspx

    Att.

    Ari C. Raimundo
    sábado, 11 de julho de 2009 01:03
  • Krust,

    Conforme dito, você pode usar algumas ferramentas que fazem o mapeamento objeto relacional como DataSet Tipado ou EntityFrameWork, até a respeito do EF estou escrevendo muitas coisas legais dele no meu blog -> http://nelsonborgesjr.spaces.live.com/blog/

    A grande vantagem de se utilizar as ferramentas acima é que as mesmas incorporam uma série de padrões de código que ajudam minimizando o desenvolvimento e melhorando a performance e qualidade do código, uma vez que as mesmas são feitas em cima de design patterns. No entando nada impede você fazer na mão, mas no seu caso, se me permite posso dar algumas sugestões que podem melhorar ?:

    - Classe Gerenciador de Conexão
       - Deixe a string de conexão no config de sua aplicação de preferência criptografada. Veja -> http://www.dreamincode.net/code/snippet1676.htm
       - Se fizer o item acima não há necessidade de ter esta classe, pois poderá ler direto do config, detalhe que sua classe estatica poderá ter menos performance em ambientes multi-thread, então avalie o custo/beneficio.

    - Método selectInadimplenteLista
       -
    O Objeto SqlConnection implementa a interface IDispose, por isso você pode usar o using, exemplo: http://blog.dmbcllc.com/2008/11/10/dispose-with-using/
       - Se fizer o item acima não precisa do CommandBehavior.CloseConnection, pois o using irá controlar quando fechar a conexão, isso irá tirar mais um peso do DataReader.

    Lembre-se que performance não apenas sistema, verifique como esta seu banco de dados, Indices, Estatisticas na tabela, a configuração do servidor de banco, para isso pode usar o perfmon e o profile, se mesmo assim continuar ruim, você pode pensar em alguma solução de cache de dados -> http://www.devx.com/dotnet/Article/31158.


    Abraço,

    Nelson Borges - http://nelsonborgesjr.spaces.live.com/blog/
    quinta-feira, 16 de julho de 2009 03:41