none
Select indexado

    Pergunta

  • Amigos como faço um select indexado?

     

    Tenho uma tabela com 35 MM e realizo um join com ela mesma e está demorando em torno de 4:00.

     

    Será que o select indexado irá ajudar?

    sexta-feira, 4 de abril de 2008 18:59

Respostas

  • Gustavo,

     

    eu somente estou consultando uma única tabela. e os campos Invoice_Account_Id e Invoice_ID são os indices da tabela D_Pgto_Ajuste_Cenario.

     

    E ai existe ou não "select indexado"?

    sexta-feira, 4 de abril de 2008 19:51
  • Olá Felipe,

     

    É uma possibilidade. Acho que para confirmarmos bastaria que o Daniel transformasse o UPDATE em SELECT. Se o mesmo demorar, certamente a Subquery é a contenção.

     

    Notei também que há um campo na cláusula WHERE que não sugeri na proposta de indexação.

     

    Daniel você poderia indexar o campo VL_Dif ? Como ele está sendo utilizado também, um índice poderia ser útil.

     

    [ ]s,

     

    Gustavo

     

    sexta-feira, 4 de abril de 2008 20:22
  • Olá Daniel,

     

    Como múltiplas soluções (todas fundamentadas) estão aparecendo, eu recomendo que você implemente uma por vez e verifique os resultados. Se formos adicionar todos os índices propostos, o desempenho pode melhorar por um lado (o da subquery) e piorar por outro (o do update que também será afetado já que atualiza os índices).

     

    [ ]s,

     

    Gustavo

     

    sexta-feira, 4 de abril de 2008 20:58
  •  

    Exatamente como o gustavo comentou. Cuidado com muitas idéias de uma vez só. Mas na verdade a indexação acaba sendo uma verdadeira e interessante arte. Pense também nos inserts. Como você comentou que a tabela é grande, me parece que recebe muitos inserts. Lembre-se que em qualquer insert e update você estará atualizando indices  também. Tente sempre encontrar o melhor conjunto de indices para seus selects sem contudo atrapalhar os inserts e updates (falando de desempenho). Exitstem muitas técnicas para que voce possa alanizar as melhores colunas para indices como por exemplo DBCC SHOW_STATISTICS ('Tabela', 'Coluna') onde você irá analizar densidade/seletividade de suas colunas, desde que se tenha estatísticas criadas. Para mais informações aqui no msdn voce encontra nesse link: http://msdn2.microsoft.com/en-us/library/aa258821(SQL.80).aspx

     

    Bem... discutir sobre como escolher indices é interessante mas esse é um ponto que pode te ajudar em outros casos.

     

    Mas lebre-se de não carregar muito sua tabela com indices e principalmente não crie um indice para cada situação que possa surgir na vida. Exceto, claro, em algumas excessões. E o que viria a ser um grande número de índices? Em um dos sistemas críticos onde administro atualmente, encontrei uma tabela que o desenvolvedor resolveu criar um indice para cada select que lhe passava pela cabeça. resultado: 71 indices em uma tabela aki, 10 indices em outra tabela ali (sendo essa a tabela "chave" de todo o sitema, com muitos inserts e muitas consultas).

     

    Ok?

    sábado, 5 de abril de 2008 03:33
  • DrAlves,

     

    Legal, isso mostra o porque devemos planejar a implementação de índices sobre uma table!!!

    segunda-feira, 7 de abril de 2008 13:29
  • Ok Daniel,

     

    Espero que o desempenho tenha ficado aceitável.

     

    [ ]s,

     

    Gustavo

     

    segunda-feira, 7 de abril de 2008 13:33

Todas as Respostas

  • Olá Daniel,

     

    Nunca havia escutado essa expressão, mas imagino que você esteja se referindo a uma instrução SELECT que use um índice (e não a uma instrução SELECT que force um índice). Bom, o ideal é que nesse caso, você indexe as colunas utilizadas nos JOINs ainda que seja uma única tabela envolvida.

     

    Você pode postar o SELECT ?

     

    [ ]s,

     

    Gustavo

    sexta-feira, 4 de abril de 2008 19:10
  • DrAlves,

     

    Select indexado!!!

     

    Você desejar utilizar um índice no select?

     

    A table que você esta utilizando possui índice?

    sexta-feira, 4 de abril de 2008 19:22
  • Cara essa foi a expressão que chegou até a minha pessoa. Mas o que elz quiz dizer é exatamente isso " uma instrução Select que use um indice". Bom a tabela em questão já possui index no campo Invoice_Id.

     

    Mas o que eu gostaria de saber é como ficaria esse select com esse tal de "select indexado".

     

     

     

     

    Update D_Pgto_Ajuste_Cenario
     Set Vl_Dif = SubQ.Vl_Dif
    From D_Pgto_Ajuste_Cenario DPAC
     Inner Join (Select Invoice_Id, Sum(Vl_Aberto + Vl_Pgto + Vl_Ajuste) as Vl_Dif
          From D_Pgto_Ajuste_Cenario
          Group By Invoice_Id) SubQ
    On DPAC.Invoice_Id = SubQ.Invoice_Id
    Where DPAC.Vl_Dif = 0
    And DPAC.Invoice_Account_Id = '50306'

    sexta-feira, 4 de abril de 2008 19:34
  • Olá Daniel,

     

    Nesse caso mais de uma tabela está envolvida. Sugeriria os seguintes índices:

     

    1 - Indexar o campo Invoice_Account_Id da tabela DPAC (Esse talvez seja o índice mais importante dessa consulta)
    2 - Indexar a coluna Invoice_ID das duas tabelas (DPAC e SubQ)

     

    [ ]s,

     

    Gustavo

    sexta-feira, 4 de abril de 2008 19:44
  • Gustavo,

     

    eu somente estou consultando uma única tabela. e os campos Invoice_Account_Id e Invoice_ID são os indices da tabela D_Pgto_Ajuste_Cenario.

     

    E ai existe ou não "select indexado"?

    sexta-feira, 4 de abril de 2008 19:51
  • Olá Daniel,

     

    Analisando melhor você tem razão. Acabei me enganando com a Subquery que eu mesmo fiz. De qualquer forma as recomendações são válidas. Como o campo Invoice_ID já está indexado, siga a recomendação número 1.

     

    Eu nunca vi alguém usar esse termo em nenhuma bibliografia. Quando usamos um termo desconhecido estamos utilizando um neologismo, ou seja, palavras inventadas. Evito utilizar neologismos quando eles podem provocar confusões. O neologismo "Select Indexado" não deixar nada ambíguo mas prefiro simplesmente falar em uma consulta que usa o índice (de preferência eficientemente).

     

    [ ]s,

     

    Gustavo

     

    sexta-feira, 4 de abril de 2008 20:02
  • DrAlves,

     

    saindo um pouquinho da questão do termo "select indexado...", creio que o problema não esteja somente com a indexação da tabela. Tentei simular a consulta entre as minhas bases de homologação e, ao meu ver, somente indice não vai resolver por completo.

     

    Já pensou em refazer seu update com outra técnica para os inner joins e subselects?

     

    O fato é que mesmo indexando a coluna citada o seu subselect, com o tanto de somas no select list, irá forçar um table scan. certamente essa é a porção mais lenta; calcular e depois juntar com a porção de "fora" do subselect. esse certamente é seu ponto de conteção (mesmo indexando).

    sexta-feira, 4 de abril de 2008 20:09
  • Olá Felipe,

     

    É uma possibilidade. Acho que para confirmarmos bastaria que o Daniel transformasse o UPDATE em SELECT. Se o mesmo demorar, certamente a Subquery é a contenção.

     

    Notei também que há um campo na cláusula WHERE que não sugeri na proposta de indexação.

     

    Daniel você poderia indexar o campo VL_Dif ? Como ele está sendo utilizado também, um índice poderia ser útil.

     

    [ ]s,

     

    Gustavo

     

    sexta-feira, 4 de abril de 2008 20:22
  • Hahhaa, "Select Indexado" foi boa, acho que é uma variação de "Carro Tunado".

     

    Desculpe não consegui resistir.

     

    Falando sério, uma das opções seria criar um indice na tabela D_Pgto_Ajuste_Cenario campos Invoice_Id, Vl_Aberto, Vl_Pgto, Vl_Ajuste.

     

    Code Snippet

    create index ix_Nome ON D_Pgto_Ajuste_Cenario(Invoice_Id, Vl_Aberto, Vl_Pgto, Vl_Ajuste)

     

     

    sexta-feira, 4 de abril de 2008 20:30
  • Olá Daniel,

     

    Como múltiplas soluções (todas fundamentadas) estão aparecendo, eu recomendo que você implemente uma por vez e verifique os resultados. Se formos adicionar todos os índices propostos, o desempenho pode melhorar por um lado (o da subquery) e piorar por outro (o do update que também será afetado já que atualiza os índices).

     

    [ ]s,

     

    Gustavo

     

    sexta-feira, 4 de abril de 2008 20:58
  •  

    Exatamente como o gustavo comentou. Cuidado com muitas idéias de uma vez só. Mas na verdade a indexação acaba sendo uma verdadeira e interessante arte. Pense também nos inserts. Como você comentou que a tabela é grande, me parece que recebe muitos inserts. Lembre-se que em qualquer insert e update você estará atualizando indices  também. Tente sempre encontrar o melhor conjunto de indices para seus selects sem contudo atrapalhar os inserts e updates (falando de desempenho). Exitstem muitas técnicas para que voce possa alanizar as melhores colunas para indices como por exemplo DBCC SHOW_STATISTICS ('Tabela', 'Coluna') onde você irá analizar densidade/seletividade de suas colunas, desde que se tenha estatísticas criadas. Para mais informações aqui no msdn voce encontra nesse link: http://msdn2.microsoft.com/en-us/library/aa258821(SQL.80).aspx

     

    Bem... discutir sobre como escolher indices é interessante mas esse é um ponto que pode te ajudar em outros casos.

     

    Mas lebre-se de não carregar muito sua tabela com indices e principalmente não crie um indice para cada situação que possa surgir na vida. Exceto, claro, em algumas excessões. E o que viria a ser um grande número de índices? Em um dos sistemas críticos onde administro atualmente, encontrei uma tabela que o desenvolvedor resolveu criar um indice para cada select que lhe passava pela cabeça. resultado: 71 indices em uma tabela aki, 10 indices em outra tabela ali (sendo essa a tabela "chave" de todo o sitema, com muitos inserts e muitas consultas).

     

    Ok?

    sábado, 5 de abril de 2008 03:33
  • Amigos,

     

    obrigado pela ajuda e me desculpem pelo termo "select indexado", mas foi o mesmo termo que chegou até a minha pessoa.

     

    Como relação o select foi executado mais rápido do que o update, mais pelo visto não tenho mais o que fazer. Agradeço a ajuda de todos.

     

    Um grande abraço a todos.

    segunda-feira, 7 de abril de 2008 12:30
  • Bom Dia Daniel,

     

    E as propostas de índices ? Elas foram implementadas ?

     

    [ ]s,

     

    Gustavo

     

    segunda-feira, 7 de abril de 2008 12:45
  • Foram implementadas sim. Porém somente adcionei mais um indice que foi no campo Vl_Dif.

     

    E a performance melhorou em 20%.

    segunda-feira, 7 de abril de 2008 13:27
  • DrAlves,

     

    Legal, isso mostra o porque devemos planejar a implementação de índices sobre uma table!!!

    segunda-feira, 7 de abril de 2008 13:29
  • Ok Daniel,

     

    Espero que o desempenho tenha ficado aceitável.

     

    [ ]s,

     

    Gustavo

     

    segunda-feira, 7 de abril de 2008 13:33