Qual a melhor solução para banco com milhões de registros?

3,050 views
Skip to first unread message

Walter

unread,
Oct 22, 2008, 4:03:00 PM10/22/08
to LISTA PHP
Boa Tarde.

Estou fazendo um sistema de armazenamento de links e estou passando
por alguns problemas que infelizmente não consegui achar a melhor
solução para isto.

Ele chegou a ter 35 milhões de registros e uma consulta na tabela
estava demorando.
Era apenas uma tabela e agora estou refazendo o sistema e remodelei o
banco da seguinte forma:

Tabela: links
Campos:
id: INT(10)
link: VARCHAR(200)
created: DATE
flag: INT(2)

Possui 2 index: Uma para flag e uma para link.

Tabela: sublinks
Campos:
link_id: INT(10)(FK)
sublink: VARCHAR(1000)
created: DATE
flag: INT(2)

Possui 2 index: Uma para link_id e outra que tem 2 campos (link_id e
flag)


Pensei em fazer desta forma porque ai não preciso colocar o endereço
completo em cada sublink adicionado:
http://www.site.com/algo/teste.php

o http://www.site.com seria gravado na tabela links e o restante na
tabela sublinks relacionando com a tabela links

Uma das complicações é que o sublink não pode ser repetido, ou seja:
vou ter que fazer várias consultas antes de cada inserção no banco
para ver se ele é ou não duplicado. (poderia criar um trigger que
setasse a flag com um numero diferente e depois limpar todos os campos
que tivessem a flag respectiva, porém não sei se muda muito)

Outra foi o fato de o banco estar com mais de 5 gigas e ter
comprometido a integridade do mesmo (perdemos o banco e tivemos que
restaurar um mais antigo)


Cheguei a pensar em colocar em um XML pois ai poderia dividir em
vários arquivos pequenos, porém, meu amigo falou que mesmo assim
ficaria mais lento e inviável de fazer.


O que me recomendam pesquisar para resolver este e possíveis problemas
futuros?

Obrigado.

Paulo Diovani

unread,
Oct 22, 2008, 4:21:43 PM10/22/08
to list...@googlegroups.com
Procure otimizar suas consultas, criando índices para todas as
possíveis consultas. E então divida sua base em um cluster (vários
servidores para a mesma base).

Para isso você vai precisar procurar a documentação de seu SGBD.

2008/10/22 Walter <lobo...@gmail.com>:
--
Paulo Diovani
pa...@diovani.com
+55 51 8146 5413
___________________
http://www.diovani.com

Edgar da Silva (Fly2k)

unread,
Oct 22, 2008, 4:42:08 PM10/22/08
to list...@googlegroups.com
Talvez você também precise de um tuning no seu banco de dados...uma
mlhor especificação de hardware.

2008/10/22 Walter <lobo...@gmail.com>:

--
Abraços
Edgar Ferreira da Silva

-----
Aprenda PHP, cole códigos, saiba das vagas de empregos:
http://www.manjaphp.com.br

Mário Júnior

unread,
Oct 22, 2008, 6:27:19 PM10/22/08
to list...@googlegroups.com
Desculpa a pergunta.. mas qual banco de dados está usando?


2008/10/22 Edgar da Silva (Fly2k) <silva...@gmail.com>



--
Mário de Souza Júnior
Programador Java / Adobe Flex
(44) 4009-3550 Maringá-PR
http://blog.mariojunior.com
junin...@gmail.com (gtalk, msn, etc..)

Walter

unread,
Oct 22, 2008, 6:51:20 PM10/22/08
to LISTA PHP
MySQL.

Pensei em PostGree mas não consegui argumentos convincentes para meu
chefe.

Esse negócio de dividir em vários servidores eu ouvi falar mas não
faço idéia de como fazer.

Caso eu descubra, existe possibilidade de fazer essa migração em
vários clusters?

Obrigado

On 22 out, 20:27, "Mário Júnior" <juninho...@gmail.com> wrote:
> Desculpa a pergunta.. mas qual banco de dados está usando?
>
> 2008/10/22 Edgar da Silva (Fly2k) <silva.ed...@gmail.com>
>
>
>
> > Talvez você também precise de um tuning no seu banco de dados...uma
> > mlhor especificação de hardware.
>
> > 2008/10/22 Walter <loboci...@gmail.com>:
> > > ohttp://www.site.comseria gravado na tabela links e o restante na
> juninho...@gmail.com (gtalk, msn, etc..)

Alex de Azevedo

unread,
Oct 23, 2008, 6:55:12 AM10/23/08
to LISTA PHP
Cara, uma ideia mais simples e mais viavel do que um cluster, tuning
etc.. seria você tentar pensar em uma forma de quebrar essa tabela de
links e sublinks em mais de uma... ou de repente criar uma tabela de
keywords com níveis de relevancia pra posicionar os resultados, por
exemplo.. ou de repente armazenar o link no banco quebrado em blocos..
enfim, são N possibilidades.. mas acredito que a forma mais rápida e
viavel de tentar otimizar essas consultas seja fazendo isso..além é
claro, de indexar estrategicamente as tabelas a serem consultadas,
etc. Pensa nisso!.. e poste aqui a experiencia que for bem sucedida!!
considero esse um tópico legal, importante e útil pra ser discutido :P

Abraço,
> ohttp://www.site.comseria gravado na tabela links e o restante na

Mário Júnior

unread,
Oct 23, 2008, 7:36:08 AM10/23/08
to list...@googlegroups.com
Well... 35 milhoes de dados é um volume considerável.
Não duvido da capacidade do MySQL, mas acho q se fizesse um benchmark com outros bancos seria interessante.....

Postgree ou a versão free do Oracle (se não passar de 2gb).
Tínhamos um banco de 4gb em interbase e ao migrar para Oracle ficou 1gb de tamanho físico e os dados bem mais rápidos para consultas. Faça uns testes por aí tb (fogo é vc exportar esses dados.. vai demoráááá =D)

Comece a considerar a hipótese de contratar uma consultoria especializada em DBA.
Sou a favor de: "cada macaco em seu galho". Claro, q sempre dou uns pitacos de dba tb... mas qnd a coisa engrossa, é melhor contar com especialistas. Não deve ser caro (uns 200R$/hora) , e em poucas horas (talvez 2 ou 3) ele pode resolver seu caso.

Boa sorte.



--
Mário de Souza Júnior
Programador Java / Adobe Flex

Edgar da Silva (Fly2k)

unread,
Oct 23, 2008, 8:00:19 AM10/23/08
to list...@googlegroups.com
Realmente, uma consultoria seria melhor pra vc, do que a gente ficar
chutando "SE".... a empresa em que trabalho tem pessoas qualificadas
pra isso. Se quiser posso te passar o contato. E eles podem te
arranjar argumentos, caso seja a necessidade, para convencer seu
chefe.

2008/10/23 Mário Júnior <junin...@gmail.com>:

--

Cristian Trentin

unread,
Oct 22, 2008, 10:45:45 PM10/22/08
to list...@googlegroups.com
Walter amigão... argumentos para trocar o MySql pelo Postgre ? Na verdade eu acho que nem precisa... mas basta uma busca rápida no Google para você ver que existem varias..

A mas o PostgreSql tem baixa performace comparado com o Mysql..... hum... que mais ?

Postgre gerencia tabelas como o Mysql nunca fará...

Só para vc ter uma idéia...

Atualmente Gerencio um sistema que usa... 123 tabelas....

Algumas Tabelas com mais de 65 milhões de registros...

Temos 23.000 acessos dias que geram algo perto de 65 mil registros por dia...

O sistema é em PHP com Postgre...

Eu não me arrependi... posso lhe dizer que deu muito trabalho para migrar os dados do MySql para o Postgre.. mas agora... é só alegria...


[]s
Cristian Trentin

Eduardo Maçan

unread,
Oct 23, 2008, 8:24:58 AM10/23/08
to list...@googlegroups.com
Só o fato de ter a herança do código do Ingres e ter suporte a
transações desde a época em que o mysql ainda usava chupeta já seria o
bastante para me convencer :)

Na verdade, foi :)

2008/10/23 Cristian Trentin <admd...@gmail.com>:
--
Eduardo Marcel Maçan
http://eduardo.macan.eng.br

Paulo Diovani

unread,
Oct 23, 2008, 8:30:07 AM10/23/08
to list...@googlegroups.com
> A mas o PostgreSql tem baixa performace comparado com o Mysql..... hum...
E o problema do Walter, atualmente , é justo a performance.

Sinceramente, uma base de dados sem um bom DBA, fica uma péssima base de dados.
O MySQL é muito mais rápido que o PostgreSQL, principalmente se você
estiver utilizando tabelas MyISAM, porém ele é em questão de recursos,
não tem muito poder pra criar funções ou trabalhar com integridade de
dados.

Eu sugeri clusters anteriormente, mas você tem definitivamente poucos
dados para um cluster ser necessário.

Tabelas MyISAM podem, normalmente, guardar até 2^32 registros (mais de
4 bilhões de linhas), e este valor ainda pode ser aumentado para
2^64,se o MySQL for compilado com suporte a grandes tabelas.
InnoDB, que suporta transações e referências, pode conter muito mais
do que isso (na verdade acho que não tem limites).
http://www.shinguz.ch/MySQL/mysql_limitations.html

Sua melhor opção deve ser mesmo otimizar as consultas e/ou fazer um
upgrade de hardware.

Paulo Diovani

unread,
Oct 23, 2008, 8:37:35 AM10/23/08
to list...@googlegroups.com
2008/10/23 Eduardo Maçan <eduard...@gmail.com>:

>
> Só o fato de ter a herança do código do Ingres e ter suporte a
> transações desde a época em que o mysql ainda usava chupeta já seria o
> bastante para me convencer :)
>
> Na verdade, foi :)

Desculpe criticar, Eduardo, mas você está exibindo um ponto de vista pessoal.
MySQL e PostgreSQL são bases de dados diferentes, e devem ser
utilizadas para fins diferentes. MySQL é pra ser rápido. Postgres tem
mais recursos.

Minha preferência é MySQL, mas eu não utilizaria ele para um projeto
em uma grande organização, preferiria usar um Oracle se fosse o caso.

Cristian Trentin

unread,
Oct 23, 2008, 8:39:28 AM10/23/08
to list...@googlegroups.com
Paulo,
Performace é o que todos queremos além de segurança....

Mas como foi falado em uma palestra do PGcon 2008.. não tem almoço de graça...

Sugiro que ele faça uma busca sobre o assunto.. e digo mais.. existem boas base de dados sem DBAs....


Mas quando vc não sabe por onde começar.. corre para eles...rsrs

Aqui usamos cluster e virtuaização.. com spool de conexões... e viva o PostgreSQL

rs

[]s

2008/10/23 Paulo Diovani <pa...@diovani.com>



--
Atenciosamente,
Cristian Trentin

Eduardo Maçan

unread,
Oct 23, 2008, 8:47:35 AM10/23/08
to list...@googlegroups.com
Oi Paulo, não precisa se desculpar, sua observação é extremamente pertinente.

Eu uso Oracle, PostgreSQL e MySQL aqui, pois muitas aplicações livres
que usamos dependem de um ou outro (a maioria do MySQL pra dizer a
verdade).

Se você quer fazer algo para ser muito consultado e pouco alterado,
realmente o MySQL vai dar banho, já com o setup default e sem tunning,
por isso é tão popular em aplicações web.

Mas à medida que sua necessidade cresce, você precisa de transações,
integridade referencial sólida, suporte a grandes volumes de dados,
stored procedures, etc etc... o que eu quis dizer é que quando eu
precisei disso em um banco de dados livre (o Firebird ainda não
existia) MySQL não tinha nada disso. Nesta época, PostgreSQL era a
única solução (estou falando de mais de 10 anos), e o que quero dizer
é que, independente da qualidade e da evolução inegável do MySQL ao
longo destes anos, o PostgreSQL se beneficia muito da maturidade de
seu código, que já vinha da herança do Ingres (Postgres é um jogo de
palavras com Post (após) e Ingres (que tinha sua própria linguagem de
consulta diferente de SQL) para quem não conhece a história)

Eu concordo com você em gênero, número e grau... talvez só discorde um
pouco quanto a usar o Oracle :) Acho que a maioria das empresas no
Brasil, hoje, pode passar sem ele muito melhor do que com ele. :o)

Abração!

2008/10/23 Paulo Diovani <pa...@diovani.com>:

Walter

unread,
Oct 23, 2008, 12:09:02 PM10/23/08
to LISTA PHP
Opa Alex.

Não consegui entender muito bem esse esquema de quebrar a tabela em
mais de uma.
Seria fazer tabelas alfabéticas?

Essa de keywords também não entendi muito bem.

Queria achar alguma documentação sobre como separar o banco de dados
em vários servidores. Creio que seria a solução que meu chefe iria
gostar, ele já havia comentado.

O banco eu deixei como InnoDB pra ter uma integridade maior.

Consultoria eu iria sugerir depois que o sistema estivesse pronto e
estivesse dando certo.


Obrigado a todos pela ajuda até o momento =]




On 23 out, 10:47, "Eduardo Maçan" <eduardoma...@gmail.com> wrote:
> Oi Paulo, não precisa se desculpar, sua observação é extremamente pertinente.
>
> Eu uso Oracle, PostgreSQL e MySQL aqui, pois muitas aplicações livres
> que usamos dependem de um ou outro (a maioria do MySQL pra dizer a
> verdade).
>
> Se você quer fazer algo para ser muito consultado e pouco alterado,
> realmente o MySQL vai dar banho, já com o setup default e sem tunning,
> por isso é tão popular em aplicações web.
>
> Mas à medida que sua necessidade cresce, você precisa de transações,
> integridade referencial sólida, suporte a grandes volumes de dados,
> stored procedures, etc etc... o que eu quis dizer é que quando eu
> precisei disso em um banco de dados livre (o Firebird ainda não
> existia) MySQL não tinha nada disso. Nesta época, PostgreSQL era a
> única solução (estou falando de mais de 10 anos), e o que quero dizer
> é que, independente da qualidade e da evolução inegável do MySQL ao
> longo destes anos, o PostgreSQL se beneficia muito da maturidade de
> seu código, que já vinha da herança do Ingres (Postgres é um jogo de
> palavras com Post (após) e Ingres (que tinha sua própria linguagem de
> consulta diferente de SQL) para quem não conhece a história)
>
> Eu concordo com você em gênero, número e grau... talvez só discorde um
> pouco quanto a usar o Oracle :) Acho que a maioria das empresas no
> Brasil, hoje, pode passar sem ele muito melhor do que com ele. :o)
>
> Abração!
>
> 2008/10/23 Paulo Diovani <pa...@diovani.com>:
>
>
>
>
>
> > 2008/10/23 Eduardo Maçan <eduardoma...@gmail.com>:

Cristian Trentin

unread,
Oct 23, 2008, 12:13:36 PM10/23/08
to list...@googlegroups.com
Eu aconselho a separar a BD em Hds diferentes....

Usar partições apenas para os indices... e por ai vai... isso da um bom resultado

Walter

unread,
Oct 23, 2008, 12:59:54 PM10/23/08
to LISTA PHP
Como faço isso Cristian?
Onde tem algum material bom para eu ler sobre isto?

Obrigado.

Alex de Azevedo

unread,
Oct 23, 2008, 1:13:36 PM10/23/08
to list...@googlegroups.com
Fala Walter,
Quebrar as tabelas seria o seguinte..
vc teria sua tabela de links, mas teria uma outra, por exemplo de
keywords.. essas keywords podem ser o seu link quebrado de uma forma
logica. A ideia é consultar a partir dessa tabela, entendeu??
tipo isso.. hehe

Mas a ideia de fazer um cluster com certeza é uma boa opção, se vocês
tiverem como fazer!!!

Cristian Trentin

unread,
Oct 23, 2008, 1:12:44 PM10/23/08
to list...@googlegroups.com
Desculpe amigo mas não tenho nenhum material sobre isso... creio que vc entrando na lista do PostreSQL vc possa achar isso com o pessoal

Não sei se pelas regras do grupo eu posso indicar outra lista.. mas como é para ajudar... ai segue http://www.postgresql.org.br/
--
Atenciosamente,
Cristian Trentin

Walter

unread,
Oct 23, 2008, 3:14:04 PM10/23/08
to LISTA PHP
Pensei nesta seguinte solução:
Modifiquei um pouco a tabela e adicionei um campo chamado "scheme"
onde vai ficar um registro tipo INTEGER, o numero vai ser para
identificar se é http ou https e etc, poupando um pouco o volume de
dados (http://)
Outro campo para armazenar se tem ou não o www (tipo inteiro também).
No total serão poupados uns 8 caracteres.

O banco será usado para gravar e manipular os dados, depois de
organizado eu vou fazer ele exportar para um XML com o nome do link.

Será um arquivo XML estático que sera apenas usado para listar o
conteúdo dele, assim em vez de pesquisar em um banco com mais de 4GB e
milhões de registros, ele vai procurar em um arquivo especifico onde
todos os dados são relevantes para aquele site.

É uma solução viável?

Muito obrigado.


On 23 out, 15:12, "Cristian Trentin" <admder...@gmail.com> wrote:
> Desculpe amigo mas não tenho nenhum material sobre isso... creio que vc
> entrando na lista do PostreSQL vc possa achar isso com o pessoal
>
> Não sei se pelas regras do grupo eu posso indicar outra lista.. mas como é
> para ajudar... ai seguehttp://www.postgresql.org.br/
> --
> Atenciosamente,
> Cristian Trentin

Walter

unread,
Oct 23, 2008, 3:15:47 PM10/23/08
to LISTA PHP
Tentei postar o link para uma imagem e não consegui, google maluco.
Desculpem o flood

http://pastebin.ca/1234957

Tiago Gigli

unread,
Oct 23, 2008, 3:19:23 PM10/23/08
to list...@googlegroups.com
desnormalizacao. crie tabelas de identificacao. e use campos q vc acha viavel. lembra q tinyint eh mais rapido e ocupa menos espaco q um int(11)
--------------------------------------------
Tiago Gigli
MyGSM: +55 (15) 8116-5168
Eml/MSN/GTalk: ti...@gigli.com.br
Twitter: tiagogigli
--------------------------------------------
http://perolasdocar.blogspot.com/
http://tiago.gigli.com.br


2008/10/23 Walter <lobo...@gmail.com>

Aurelio Saraiva

unread,
Oct 23, 2008, 3:20:08 PM10/23/08
to list...@googlegroups.com
Usa tinyint pra salvar estado booleanos...


2008/10/23 Walter <lobo...@gmail.com>

Alex de Azevedo

unread,
Oct 23, 2008, 3:23:19 PM10/23/08
to list...@googlegroups.com
Exatamente..
foi isso que eu quis dizer com o lance de keywords..tabelas de
identificação.. busque a partir delas, até formar base suficiente pra
catar o registro do link que você quer na tabela dos links

Tiago Gigli wrote:
> desnormalizacao. crie tabelas de identificacao. e use campos q vc acha
> viavel. lembra q tinyint eh mais rapido e ocupa menos espaco q um int(11)
> --------------------------------------------
> Tiago Gigli
> MyGSM: +55 (15) 8116-5168
> Eml/MSN/GTalk: ti...@gigli.com.br <mailto:ti...@gigli.com.br>
> Twitter: tiagogigli
> --------------------------------------------
> http://perolasdocar.blogspot.com/
> http://tiago.gigli.com.br
>
>
> 2008/10/23 Walter <lobo...@gmail.com <mailto:lobo...@gmail.com>>
>
>
> Tentei postar o link para uma imagem e não consegui, google maluco.
> Desculpem o flood
>
> http://pastebin.ca/1234957
>
>
> On 23 out, 17:14, Walter <loboci...@gmail.com
> <mailto:loboci...@gmail.com>> wrote:
> > Pensei nesta seguinte solução:
> > Modifiquei um pouco a tabela e adicionei um campo chamado "scheme"
> > onde vai ficar um registro tipo INTEGER, o numero vai ser para
> > identificar se é http ou https e etc, poupando um pouco o volume de
> > dados (http://)
> > Outro campo para armazenar se tem ou não o www (tipo inteiro
> também).
> > No total serão poupados uns 8 caracteres.
> >
> > O banco será usado para gravar e manipular os dados, depois de
> > organizado eu vou fazer ele exportar para um XML com o nome do link.
> >
> > Será um arquivo XML estático que sera apenas usado para listar o
> > conteúdo dele, assim em vez de pesquisar em um banco com mais de
> 4GB e
> > milhões de registros, ele vai procurar em um arquivo especifico onde
> > todos os dados são relevantes para aquele site.
> >
> > É uma solução viável?
> >
> > Muito obrigado.
> >
> > On 23 out, 15:12, "Cristian Trentin" <admder...@gmail.com

Bernardo Vieira

unread,
Oct 23, 2008, 4:36:13 PM10/23/08
to list...@googlegroups.com
Walter wrote:

>> Modifiquei um pouco a tabela e adicionei um campo chamado "scheme"
>> onde vai ficar um registro tipo INTEGER, o numero vai ser para
>> identificar se é http ou https e etc, poupando um pouco o volume de
>> dados (http://)
>> Outro campo para armazenar se tem ou não o www (tipo inteiro também).
>> No total serão poupados uns 8 caracteres.
>>

INT(1) não quer dizer int de 1 bit. O número entre parêntesis determina
apenas a forma de exibição do campo, ou seja, INT(1) e INT(11) ocupam os
mesmos 4 bytes e armazenam valores entre -2147483648 e 2147483647
(signed) ou 0 e 4294967295 (unsigned), no seu caso use tinyint unsigned
(1 byte, 0 a 255).

Walter

unread,
Oct 23, 2008, 3:40:02 PM10/23/08
to LISTA PHP
Já fiz a modificação para Tinyint, não sei o que me deu usar o int

O que não entendi foi o "forma de exibição".

Obrigado.

Bernardo Vieira

unread,
Oct 23, 2008, 4:47:30 PM10/23/08
to list...@googlegroups.com
Diretamente do manuel :
"Another extension is supported by MySQL for optionally specifying the
display width of integer data types in parentheses following the base
keyword for the type (for example, |INT(4)|). This optional display
width is used to display integer values having a width less than the
width specified for the column by left-padding them with spaces.

The display width does /not/ constrain the range of values that can be
stored in the column, nor the number of digits that are displayed for
values having a width exceeding that specified for the column. For
example, a column specified as |SMALLINT(3)| has the usual |SMALLINT|
range of |-32768| to |32767|, and values outside the range allowed by
three characters are displayed using more than three characters."

O número entre parêntesis espefica a largura que mysql vai usar para
mostar o resultado, ie, quantos zeros a esquerda ele vai colocar para
valores que ocupam menos casas que o especificado, por exemplo, para INT(4):
1 => 0001
54130 => 54130

Acontece que como o php tem uma camada de abstração intermediária quando
o resultado chega para você ele já chega sem os zeros à esquerda. Se
você executar a query no console do mysql vai ver o resultado com o padding.

Wagner Bonfiglio

unread,
Oct 23, 2008, 3:52:38 PM10/23/08
to list...@googlegroups.com
Qual é o tipo do campo que os links estão armazenados?? 
Não sei quais existem no MySQL, mas sei que no POSTGRESQL faz uma P*** diferença usar TEXT, CHAR(50), CHARACTER VARYING(50), etc... Talvez você possa desperdiçar espaço usando um CHAR mas compensa na performance que é muito melhor...

2008/10/23 Bernardo Vieira <bvieir...@gmail.com>

Walter

unread,
Oct 24, 2008, 8:54:16 AM10/24/08
to LISTA PHP
Ué.. eu tinha feito uma resposta ontem e ela não apareceu.

Já fiz estas modificações, espero que de uma melhora considerável no
sistema mais a frente =]

O que seria esta forma de exibição?

Obrigado.


On 23 out, 18:36, Bernardo Vieira <bvieira.li...@gmail.com> wrote:

Walter

unread,
Oct 24, 2008, 8:55:50 AM10/24/08
to LISTA PHP
Me desculpem o post duplicado, não havia visto o link para as páginas
recentes (mania do google de modificar o padrão das coisas).
Só fui perceber quando postei novamente e ele não apareceu.

Obrigado.

Adan Nada

unread,
Oct 24, 2008, 4:18:43 PM10/24/08
to LISTA PHP
Sobre o Cluster em Mysql, no manual tem passa-a-passo como fazer.
Mas antes disso, sugiro revisar a indexação, slow queries,
configurações (tuning) do banco. Feito isso, se não resolver, partir
pro cluster.
Se precisar de uma mão, manda aí.
Costumo acessar o seguinte blog sobre performance no MySQL:
http://www.mysqlperformanceblog.com/
Com certeza vai encontrar lá algo que seja do seu interesse.

Falou

Walter

unread,
Oct 27, 2008, 8:02:20 PM10/27/08
to LISTA PHP
Vou pesquisar =]

Muito obrigado pela ajuda de todos.

Alexandre Gaigalas

unread,
Oct 27, 2008, 10:32:08 PM10/27/08
to list...@googlegroups.com
Não li os demais posts portanto posso dar dicas repetidas. Tenho experiência com tabelas gigantes e a sorte de ter um DBA na minha equipe de desenvolvimento. Desenvolvo um sistema com uma tabela de 55 colunas que possui 125 milhões de registros.

O segredo é criar os índices DIREITO. Não adianta criar índices sem planejar antes. Faça uso do EXPLAIN do MySQL, se não souber usar procure informações sobre ele...

http://dev.mysql.com/doc/refman/5.0/en/using-explain.html

Procure evitar campos NULL nos registros indexados.

Lembre-se que os índices tem que combinar com a pesquisa. Se você cria dois índices separados, um para o link e um para a flag, uma consulta que usa ambas as colunas não terá muita otimização. Você precisa criar um único índice contendo as duas colunas. Se você faz três tipos de consultas:

-Por link
-Por flag
-Por link e flag

Você terá que criar três índices, exatamente com as mesmas condições, cada um focado específico para aquela busca. Geralmente isso não seria necessário em um sistema menor, mas como é uma tabela monstro, a otimização ao extremo é necessária.

Se você está fazendo a pesquisa por LIKE (por exemplo, buscando todos os links que começam com "http://www.google.com"), poderia quebrar a tabela em mais campos. Uma URL "http://www.google.com/search/arquivo.html?q=abc" ficaria assim:

Esquema varchar(6) (http)
Subdominio (www)
Dominio (google.com)
Caminho (/search)
Arquivo (arquivo.html)
Query (?q=abc)

Dessa forma, você poderia fazer buscas utilizando operador "=" ao invés do Like, que é muito mais rápido:

SELECT CONCAT(Esquema,':/'',Subdominio,'.',Dominio,Caminho,'/',Arquivo,Query) FROM Links WHERE Esquema = 'http' AND Subdominio = 'www' AND Dominio = 'google.com'

Você teria que criar um índice nos campos "Esquema", "Subdominio" e "Dominio", nesse caso.

Abraço,

--
Alexandre Gomes Gaigalas
alex...@gaigalas.net
http://Alexandre.Gaigalas.Net

2008/10/22 Walter <lobo...@gmail.com>

Boa Tarde.

Estou fazendo um sistema de armazenamento de links e estou passando
por alguns problemas que infelizmente não consegui achar a melhor
solução para isto.

Ele chegou a ter 35 milhões de registros e uma consulta na tabela
estava demorando.
Era apenas uma tabela e agora estou refazendo o sistema e remodelei o
banco da seguinte forma:

Tabela: links
Campos:
id: INT(10)
link: VARCHAR(200)
created: DATE
flag: INT(2)

Possui 2 index: Uma para flag e uma para link.

Tabela: sublinks
Campos:
link_id: INT(10)(FK)
sublink: VARCHAR(1000)
created: DATE
flag: INT(2)

Possui 2 index: Uma para link_id e outra que tem 2 campos (link_id e
flag)


Pensei em fazer desta forma porque ai não preciso colocar o endereço
completo em cada sublink adicionado:
http://www.site.com/algo/teste.php

o http://www.site.com seria gravado na tabela links e o restante na
tabela sublinks relacionando com a tabela links

Uma das complicações é que o sublink não pode ser repetido, ou seja:
vou ter que fazer várias consultas antes de cada inserção no banco
para ver se ele é ou não duplicado. (poderia criar um trigger que
setasse a flag com um numero diferente e depois limpar todos os campos
que tivessem a flag respectiva, porém não sei se muda muito)

Outra foi o fato de o banco estar com mais de 5 gigas e ter
comprometido a integridade do mesmo (perdemos o banco e tivemos que
restaurar um mais antigo)


Cheguei a pensar em colocar em um XML pois ai poderia dividir em
vários arquivos pequenos, porém, meu amigo falou que mesmo assim
ficaria mais lento e inviável de fazer.


O que me recomendam pesquisar para resolver este e possíveis problemas
futuros?

Obrigado.






Reply all
Reply to author
Forward
0 new messages