Clipper On Line • Ver Tópico - Índice no SQL/MySQL
Mudar para estilo Clássico
Discussão sobre SQL
Postar uma resposta

Índice no SQL/MySQL

11 Ago 2019 01:11

É básico... mas tem gente que não sabe....
Ainda vou alterar, nem sei qual vai ser a diferença, mas sei que vai ter.
Atualizando 1 milhão de CEPs sem índice, previsão 96 horas.

cep.png

Índice no SQL/MySQL

11 Ago 2019 01:17

cep.png


cep2.png


Reduziu pra 3 horas e meia.

Ainda estou achando demorado, vou ver o que dá pra fazer....

Índice no SQL/MySQL

11 Ago 2019 01:33

cep.png


Agora alterei pra excluir 200 por vez, reduziu pra 2 horas.

Conclusão:

SQL pode trabalhar sem índice, mas isso não significa que pode ficar sem índice
Como eu já disse por aqui, não é a quantidade de registros que conta, e sim a quantidade de comandos.
Excluir um registro por vez é mais demorado do que excluir vários por vez.

Mas ainda estou achando demorado.
Pelo menos reduziu de 96 horas pra 2 horas.... de 4 dias pra 2 horas...

Estou fazendo por etapa, porque o arquivo dos correios tá uma merd. em codepage.
Isso é só a parte que não precisa mexer, por isso estou achando demorado, porque parece que vai longe...

Índice no SQL/MySQL

11 Ago 2019 01:42

Ok. errei na comparação do comando: Len( cCep ) ao invés de Len( aDeleteList ).
A previsão se manteve.

Índice no SQL/MySQL

11 Ago 2019 01:56

O lado bom é que já acabou...
O lado ruim... tem mais de 1 milhão de endereços pra corrigir...
Mas isso já é outra história...
Agora mostra mais demorado, porque está mostrando cada um na tela, então é normal.

cep.png

Índice no SQL/MySQL

11 Ago 2019 13:08

Também tinha errado no comando kkkkkk

cSql = cSql + StringSql( cSql )

Ao invés de adicionar CEP, fiquei multiplicando o comando kkkk
Não deu mensagem de erro, apenas o programa tinha abortado.
Isso era pra limpar os CEPs ok, então sem problemas, nenhum prejuízo de processamento.

Índice no SQL/MySQL

22 Ago 2019 04:01

Quando tudo tava pronto.... errei o comando e apaguei tudo kkkkk
Mas agora ficou mais rápido ainda, deixei mais processamento por conta do MySql.
Como eu já disse por aqui, sou principiante nisso ainda.
Daria pra melhorar o count(*) com um comando só, mas foi assim mesmo....

Código:
   nTotal := 0
   Rs := cnLocal:Execute( "SELECT COUNT(*) AS QTD FROM LOG_UNID_OPER" )
   nTotal += Rs:Fields( "QTD" ):Value
   Rs:CLose()
   Rs := cnLocal:Execute( "SELECT COUNT(*) AS QTD FROM LOG_GRANDE_USUARIO" )
   nTotal += Rs:Fields( "QTD" ):Value
   Rs:Close()
   Rs := cnLocal:Execute( "SELECT COUNT(*) AS QTD FROM LOG_CPC" )
   nTotal += Rs:Fields( "QTD" ):Value
   Rs:Close()
   Rs := cnLocal:Execute( "SELECT COUNT(*) AS QTD FROM LOG_LOGRADOURO" )
   nTotal += Rs:Fields( "QTD" ):Value
   Rs:Close()
   Rs := cnLocal:Execute( "SELECT COUNT(*) AS QTD FROM LOG_LOCALIDADE" )
   nTotal += Rs:Fields( "QTD" ):Value
   Rs:Close()


Pra não ter que reescrever muito fonte, acabei deixando por conta do MySQL

Código:
   Rs := cnLocal:Execute( ;
      "SELECT " + ;
      "LOG_CPC.CPC_ENDERECO AS ENDERECO, " + ;
      "'' AS BAIRRO, " + ;
      "LOG_LOCALIDADE.LOC_NOSUB AS CIDADE, " + ;
      "LOG_CPC.UFE_SG AS UF, " + ;
      "LOG_CPC.CPC_KEY_DNE AS DNEKEY " + ;
      "FROM LOG_CPC " + ;
      "INNER JOIN LOG_LOCALIDADE ON LOG_LOCALIDADE.LOC_NU_SEQUENCIAL=LOG_CPC.LOC_NU_SEQUENCIAL " + ;
      "" + ;
      "UNION ALL " + ;
      "" + ;
      "SELECT " + ;
      "LOG_UNID_OPER.UOP_ENDERECO AS ENDERECO, " + ;
      "LOG_BAIRRO.BAI_NO AS BAIRRO, " + ;
      "LOG_LOCALIDADE.LOC_NOSUB AS CIDADE, " + ;
      "LOG_UNID_OPER.UFE_SG AS UF, " + ;
      "LOG_UNID_OPER.UOP_KEY_DNE AS DNEKEY " + ;
      "FROM LOG_UNID_OPER " + ;
      "INNER JOIN LOG_BAIRRO ON LOG_BAIRRO.BAI_NU_SEQUENCIAL=LOG_UNID_OPER.BAI_NU_SEQUENCIAL " + ;
      "INNER JOIN LOG_LOCALIDADE ON LOG_LOCALIDADE.LOC_NU_SEQUENCIAL=LOG_UNID_OPER.LOC_NU_SEQUENCIAL " + ;
      "" + ;
      "UNION ALL " + ;
      "" + ;
      "SELECT " + ;
      "LOG_GRANDE_USUARIO.GRU_ENDERECO AS ENDERECO, " + ;
      "LOG_BAIRRO.BAI_NO AS BAIRRO, " + ;
      "LOG_LOCALIDADE.LOC_NOSUB AS CIDADE, " + ;
      "LOG_GRANDE_USUARIO.UFE_SG AS UF, " + ;
      "LOG_GRANDE_USUARIO.GRU_KEY_DNE AS DNEKEY " + ;
      "FROM LOG_GRANDE_USUARIO " + ;
      "INNER JOIN LOG_BAIRRO ON LOG_BAIRRO.BAI_NU_SEQUENCIAL=LOG_GRANDE_USUARIO.BAI_NU_SEQUENCIAL " + ;
      "INNER JOIN LOG_LOCALIDADE ON LOG_LOCALIDADE.LOC_NU_SEQUENCIAL=LOG_GRANDE_USUARIO.LOC_NU_SEQUENCIAL " + ;
      "" + ;
      "UNION ALL " + ;
      "" + ;
      "SELECT " + ;
      "LOG_LOGRADOURO.LOG_NOME AS ENDERECO, " + ;
      "LOG_BAIRRO.BAI_NO AS BAIRRO, " + ;
      "LOG_LOCALIDADE.LOC_NOSUB AS CIDADE, " + ;
      "LOG_LOGRADOURO.UFE_SG AS UF, " + ;
      "LOG_LOGRADOURO.LOG_KEY_DNE AS DNEKEY " + ;
      "FROM LOG_LOGRADOURO " + ;
      "INNER JOIN LOG_BAIRRO ON LOG_BAIRRO.BAI_NU_SEQUENCIAL = LOG_LOGRADOURO.BAI_NU_SEQUENCIAL_INI " + ;
      "INNER JOIN LOG_LOCALIDADE ON LOG_LOCALIDADE.LOC_NU_SEQUENCIAL = LOG_LOGRADOURO.LOC_NU_SEQUENCIAL " + ;
      "UNION ALL " + ;
      "" + ;
      "SELECT " + ;
      "'' AS ENDERECO, " + ;
      "'' AS BAIRRO, " + ;
      "LOG_LOCALIDADE.LOC_NOSUB AS CIDADE, " + ;
      "LOG_LOCALIDADE.UFE_SG AS UF, " + ;
      "LOG_LOCALIDADE.LOC_KEY_DNE AS DNEKEY " + ;
      "FROM LOG_LOCALIDADE " + ;
      "" )

Índice no SQL/MySQL

22 Ago 2019 04:21

Tentando explicar:

LOG_UNID_OPER é o CEP de unidades operacionais
LOG_CPC é o CEP de caixas postais
LOG_GRANDE_USUARIO é o CEP de grandes empresas
LOG_LOGRADOURO é o CEP de ruas
LOG_BAIRRO é onde estão cadastrados os bairros - pra trazer a descrição
LOG_LOCALIDADE é onde estão cadastradas as cidades - pra trazer a descrição, mas também o CEP de cidades

Selecionei tudo de uma vez, já trazendo a descrição dos códigos.
As estruturas tinham nomes diferentes, então o "AS nome" resolveu a diferença.
E precisei criar alguns campos fake em alguns SELECT, pra preencher campos inexistentes.
O UNION ALL juntou todas as pesquisas.

O comando é grande, mas ficou mais rápido do que trazer uma tabela e ficar pesquisando nas outras, além de menos fonte.

Dava pra fazer algo parecido no COUNT(*), depois talvez teste mudanças, pra uso futuro.

Índice no SQL/MySQL

22 Ago 2019 04:47

Deu certo deste jeito...

Código:
   Rs := cnLocal:Execute( "SELECT SUM( QTD ) AS QTD FROM " + ;
      "( SELECT COUNT(*) AS QTD FROM LOG_UNID_OPER UNION " + ;
        "SELECT COUNT(*) AS QTD FROM LOG_GRANDE_USUARIO UNION " + ;
        "SELECT COUNT(*) AS QTD FROM LOG_CPC UNION " + ;
        "SELECT COUNT(*) AS QTD FROM LOG_LOGRADOURO UNION " + ;
        "SELECT COUNT(*) AS QTD FROM LOG_LOCALIDADE ) AS TUDO" )
   nTotal := Rs:Fields( "QTD" ):Value
   Rs:Close()


Parecido com o anterior... juntei os resultados (como uma lista), e um SELECT encima dele.
Pela rede... apenas um número com o total, sem nenhum processamento no terminal.

Pra quem gostou....
Só lembrar que isso pode ser usado também com DBFs, se usar por exemplo ADS Local, que é grátis.

Pode deixar o aplicativo mais rápido, e com menos fontes, só de trocar o tipo de acesso aos DBFs.

Me parece que o LetToDb tem o acesso nesse estilo, enquanto o hbnetio apenas faz o acesso tradicional estilo dbf mesmo que seja pela internet.

Não sei como ficaria um hbnetio usando ADO.... poderia juntar o melhor dos dois mundos...
Postar uma resposta