Alto desempenho com banco de dados MySQL

Propaganda
Alto desempenho
com banco de dados MySQL
PHP Conference
30/11/2007
Boa tarde!
Jonas Silveira...
• Programador PHP Sênior
(7 anos de experiência)
• Focado em sistemas
corporativos de grande porte
• Gerente de Projetos da
Ynpar Tecnologia Ltda.
• Gestão de projetos, programação e
administração de servidores
Conteúdo da Palestra
• Sobre performance...
• PHP
- Erros comuns e
- Boas práticas
• MySQL
- Projeto Físico
- Utilização de índices
- Técnicas para ganho de desempenho
- Replicação de dados
• Dúvidas?
Como obter performance?
•
•
•
•
Tirando máximo proveito do hardware
Conhecendo os riscos
Conhecendo os “gargalos”
Reduzindo excessos
Projeto físico
Projeto físico: Localizando a lentidão
• Lentidão no servidor de dados
• Lentidão na comunicação entre
os servidores
• Lentidão no Servidor WWW
Lentidão no servidor WWW
• Pouca memória: ocorre muito swap
• Processamento insuficiente: muita lentidão
• Excesso de IO:
- disco muito cheio?
- disco lento ou danificado?
• Recursos físicos limitados na configuração do
PHP ou do Servidor WWW
• Aplicação precisa ser otimizada
Lentidão na comunicação
• Placas de rede lentas ou defeituosas
• Switch/Hub impróprio (lento) ou defeituoso
• Evitar canal de comunicação via WEB: utilizar
canal exclusivo (outras placas de rede em outro
switch ou vlan)
• Demora para conectar no MySQL:
- utilize o IP do servidor e não o nome
- thread de resolução de nomes pode ser a causa
- usar no my.cnf a opção “skip-name-resolve”
Lentidão no servidor MySQL
• Excesso de dados / Hardware inadequado
• Projeto físico inadequado
• Utilização (consultas) inadequada
Erros comuns / Boas práticas:
Contagem de registros
• SELECT COUNT(*) FROM...
- Conta o número de linhas da consulta;
- Quando a consulta é feita em mais de uma
tabela, não há otimização
• COUNT(expr): Conta o número de valores
diferentes de null de uma coluna
• Boa prática:
SELECT COUNT(1) FROM...
Erros comuns / Boas práticas:
Contagem de registros
• Ao invés da seqüência:
SELECT COUNT(*) FROM...
e depois
SELECT [...] FROM...
LIMIT 0,50
• Utilizar:
SELECT sql_calc_found_rows [...] FROM...
LIMIT 0,50
e depois
SELECT found_rows();
• Muito bom em casos em que se usa ordenação
Erros comuns / Boas práticas:
Contagem de registros
• Evite utilizar uma consulta cheia apenas para
obter o total:
$res = mysql_query(‘SELECT * FROM ...’);
$total = mysql_num_rows($res);
• Utilizar sempre função de contagem:
$res = mysql_query(‘SELECT COUNT(1) FROM ...’);
$total = mysql_result($res, 0);
Erros comuns / Boas práticas:
Transações demoradas
• Tansações: garantem que os dados foram
gravados no banco ou que nenhum dado foi
gravado
• Outros processos podem ficar aguardando
• Não devem ser demoradas
mysql_query(“BEGIN”);
#seqüencia de código demorada
mysql_query(“COMMIT”);
Erros comuns / Boas práticas:
Conexões abertas
• Feche sempre as conexões quando não precisar
mais delas
• Evite abrir duas conexões com o mesmo servidor
• As conexões podem atingir limite no banco de
dados e consomem recursos do servidor web
• Boa prática: utilização de “objetos” de conexão
utilizando destrutores (POO)
Erros comuns / Boas práticas:
Conexões persistentes
• Vantagem em poucos casos
• Conexões persistentes são boas se a sobrecarga
(overhead) de criar uma conexão ao seu servidor
SQL for alta
• Acaba gerando muitas conexões simultâneas
• Se um script realizar “lock” e for finalizado por
um erro, por exemplo, o “lock” permanece –
recomenda-se usar a função
“register_shutdown_function”
Erros comuns / Boas práticas:
Variáveis de resources
• Resource: produto de consultas
• Se possível evitar usar um nome de variável para
cada resource gerado
• Elimine resources grandes se for precisar de
recursos extras do servidor (mysql_free_result)
• Boa prática:
Defina um nome padrão (ex: $res) e sobrescreva
os resources se não forem mais utilizados
Isso poupa o servidor e facilita o Debug
Projeto físico:
Tamanho dos campos
• Cada tipo ocupa certo espaço em disco
• INT(3) ocupa o mesmo espaço que INT(11)
• Escolher o campo apropriado - ex:
Tipo
Signed
Unsigned
TINYINT
-128 a 127
0 a 255
SMALLINT
-32.768 até 32.767
0 até 65.535
MEDIUMINT
-8.388.608 até 8.388.607
0 até 16.777.215
INT
-2.147.483.648 até 2.147.483.647
0 até 4.294.967.295
Indexação de Campos
• Funcionam com índices de livros
• Organizam o acesso aos dados da memória e o
layout dos dados nos discos: consultas mais
rápidas
Índices - Armadilhas
•
•
•
•
Aumenta o espaço utilizado em disco
Inserções/Atualizações podem ficar lentas
Não utilize em campos comumente alterados
Ao realizar vários inserts, utilize inserções
extendidas
Índices - recomendações
• Crie apenas índices necessários
• Crie índices combinados de acordo com o tipo de
e pesquisa que será realizada
Ex: combinar um campo “data” com um campo
“cliente”.
• Indexe apenas a quantia necessária de caracteres
Ex: para um campo longo, como “nome” de uma
pessoa, indexe apenas os 10 primeiros caracteres
Índices - recomendações
• Nas consultas, utilize a maior quantidade de
índices possíveis
• O comando “EXPLAIN” pode ajudar a otimizar
consultas
Consultas aninhadas com
tabelas temporárias
• Bom para mesclagem de duas tabelas grandes;
• Procedimentos:
- Consulte uma das tabelas e grave o resultado
em uma tabela temporária
- Realize a consulta na outra tabela fazendo
mesclagem com a tabela temporária
• CUIDADO com a memória do servidor!
Partição Vertical
tab1a
tab1b
• Transferência das colunas (campos)
pouco utilizadas para outra tabela
• Ou seja, divisão de uma tabela
em duas, onde em uma ficam os
campos mais utilizados
• Busca aos dados mais acessados
mais rápida, pois a tabela
correspondente ficou menor
Partição Horizontal
• Transferência de registros para diferentes
tabelas ou bancos de dados
• Normalmente transfere-se registros antigos
(histórico) ou remove-os após backup
• Busca aos dados mais rápida, pois a tabela fica
menor, inclusive os arquivos de índices
Redundância de dados
• Evita consultas complexas, na maioria da vezes
que possuem JOIN, SUM, GROUP BY
• Exemplo clássico: pedidos -> pedidos_itens
(deseja-se obter o valor total do pedido somando
o valor dos itens * quantidade)
• Fácil implementação utilizando triggers
Dica: criação de histórico
• Crie um novo banco de dados, e transfira conteúdo
antigo para ele (partição horizontal
• Se puder, utilize um disco exclusivo (“multiple
tablespaces” + links simbólicos)
• Refaça as buscas utilizando UNION – ex:
Antes:
SELECT * FROM tabela1;
Depois:
SELECT * FROM tabea1
UNION
SELECT * FROM db_hist.tabela1;
Utilização de discos exclusivos
•
•
•
•
•
Permite concorrência no acesso aos dados
Bom para criar banco de dados histórico
Bom para armazenar tabelas grandes
Bom para o Log Binário
Armazene o banco de dados em disco diferente
do Sistema Operacional
Discos: utilize RAID 10
• Promove stripping
(divisão) dos dados entre
os arrays
• Promove redundância
dos dados
Servidores de Replicação
Servidores de Replicação
• Utilizado para realização de backups
• Pode-se criar um servidor “atrasado”, por
questões de segurança
• Permite escalabilidade: utilize-os para relatórios
• Para casos de espelhamento, o servidor não pode
ser lento (inferior ao servidor master)
• Se o “master” falhar, um escravo pode assumir
Servidores de Replicação
Dúvidas?
• Sites recomendados:
dev.mysql.com/doc/refman/5.0/en/
www.mysqlperformanceblog.com/
• Essa apresentação está disponível em
www.jonas-silveira.com
www.ynpar.com
Consultoria MySQL e outros serviços...
• Ynpar Tecnologia Ltda. (Alphaville - Barueri/SP)
• Serviços de Registro de Domínios,
Hospedagem, Software House,
Colocation, Administração de
Servidores, etc.
• Saiba mais em: www.ynpar.com
your network partner
• Contato:
[email protected]
Brasil: 11 4208 7476
Uma empresa do grupo
USA (Miami): 305 728 6354
Total Express
Download