O documento discute sobre otimização de desempenho em bancos de dados MySQL. Aborda tópicos como indexação de tabelas, particionamento de tabelas e otimização de consultas para melhorar a performance, como criar índices para campos frequentemente usados em consultas e usar o menor tipo de dados possível para economizar espaço.
3. Performance e Otimização de Banco de
Dados MySQL
Jeronimo Fagundes <jeronimo.fagundes@kinghost.com.br>
Rodrigo Paris <rodrigo.paris@kinghost.com.br>
4. 4
Jeronimo Fagundes
• Líder de Desenvolvimento na KingHost
• Bacharel em Ciência da Computação pela UFRGS
• Desenvolvedor PHP há 12 anos
• Trabalha com MySQL há mais de 10 anos
• Realizou a modelagem de dados para diversos sistemas que utilizam
MySQL, tendo em vista a otimização de desempenho e maximização de
throughput.
Performance e Otimização de Banco de Dados MySQL |
5. 5
Rodrigo Paris
• Analista de Infraestrutura Pleno na KingHost
• Graduando em Sistemas de Informação na PUCRS
• Administrador dos servidores de banco de dados da KingHost há 3 anos
Performance e Otimização de Banco de Dados MySQL |
6. Objetivo
Ao final do webinar, é esperado que o espectador tenha um maior
conhecimento sobre a configuração de um servidor MySQL, bem como as
melhores práticas para o desenvolvimento de aplicações que consumam
dados deste servidor.
Performance e Otimização de Banco de Dados MySQL | 6
Público alvo
Desenvolvedores de software
Demais pessoas com interesse na área de bancos de dados
7. Performance e Otimização de Banco de Dados MySQL | 7
Vídeo deste Webinar
http://www.kinghost.com.br/eventos-online
Assista também
Dicas Práticas para Otimização de Sites, de Felipe Olivaes e Felipe Braz
8. 8
Conteúdo do curso
• Indexação de Tabelas
• Particionamento de Tabelas
• Otimização de Consultas
• Infraestrutura
Performance e Otimização de Banco de Dados MySQL |
9. 1. Indexação de Tabelas
9
Como a indexação favorece a velocidade de buscas
Performance e Otimização de Banco de Dados MySQL |
10. 10
Entendendo os Índices
• O que são ?
• Quais os tipos ?
• Por que utilizar ?
• Quando utilizar ?
Performance e Otimização de Banco de Dados MySQL |
11. 11
O que são os índices ?
• Uma referência associada a uma chave (estrutura de dados)
• Estrutura que possibilita acesso a um item indexado vez
• Estrutura ou arquivo auxiliar associado a uma coleção de dados (banco
de dados)
Performance e Otimização de Banco de Dados MySQL |
12. 12
Quais os tipos de índices ?
• Compostos X Simples
• Internos X Externos
Performance e Otimização de Banco de Dados MySQL |
13. 13
Por que utilizar índices ?
• Maior Agilidade em buscas
• Menor consumo de recursos
Performance e Otimização de Banco de Dados MySQL |
14. 2. Particionamento de Tabelas
14
Dividindo sua tabela em sub-tabelas menores
Performance e Otimização de Banco de Dados MySQL |
16. 16
O que é o particionamento?
• Uso padrão:
○ Dados e índices são armazenados em arquivo único (dependente
da engine de armazenamento)
• Particionamento:
○ Dados e índices são armazenados em múltiplos arquivos, 1 por
partição
• Número máximo de partições: 1024
Performance e Otimização de Banco de Dados MySQL |
17. 17
Vantagens
• Aplicação enxerga uma tabela única
• Possibilita mais dados na tabela
○ Múltiplos arquivos
○ Adia o tamanho máximo de arquivo (depende do file system)
• Remoção de dados obsoletos facilitada
○ Pode-se remover uma partição inteira de uma vez
• Desempenho de buscas MUITO otimizado
○ Requer valor da chave de particionamento na cláusula WHERE
Performance e Otimização de Banco de Dados MySQL |
18. 18
Tipos de particionamento
• RANGE [COLUMNS*]
• LIST [COLUMNS*]
• [LINEAR] HASH
• [LINEAR] KEY
*RANGE COLUMNS e LIST COLUMNS disponíveis a partir da versão 5.5 do MySQL Server.
Performance e Otimização de Banco de Dados MySQL |
19. 19
RANGE [COLUMNS]
• Particionamento baseado em intervalos de valores
• RANGE: Uma coluna do tipo INT
○ PARTITION BY RANGE( YEAR(matricula) )
• RANGE COLUMNS: Múltiplas colunas de vários tipos
○ PARTITION BY RANGE COLUMNS ( YEAR(matricula), id_cidade )
Performance e Otimização de Banco de Dados MySQL |
21. 21
MySQL, por favor busque todos os funcionários
admitidos em 20 maio de 2015.
SELECT * FROM Funcionarios WHERE
admissao = ‘2015-05-20’
20 de maio de 2015 é uma data do mês de maio,
representado pelo número 5.
5 não é menor do que 4.
5 é menor do que 7.
Logo, esses funcionários estão todos na partição
segundo_trimestre. Buscarei apenas lá.
segundo_trimestre
-----------------
cpf
nome
admissao
4 a 6
Performance e Otimização de Banco de Dados MySQL |
22. 22
RANGE
CREATE TABLE `Funcionarios` (
`cpf` VARCHAR(14) NOT NULL,
`nome` VARCHAR(255) NOT NULL,
`admissao` DATE NOT NULL
)
PARTITION BY RANGE(MONTH(admissao)) (
PARTITION primeiro_trimestre VALUES LESS THAN (4),
PARTITION segundo_trimestre VALUES LESS THAN (7),
PARTITION terceiro_trimestre VALUES LESS THAN (10),
PARTITION quarto_trimestre VALUES LESS THAN MAXVALUE
);
Performance e Otimização de Banco de Dados MySQL |
23. 23
RANGE COLUMNS
CREATE TABLE `xyz` (
`a` INT NOT NULL,
`b` INT NOT NULL,
`c` DATETIME NOT NULL
)
PARTITION BY RANGE COLUMNS (a, MONTH(c)) (
PARTITION p0 VALUES LESS THAN (3, 7),
PARTITION p1 VALUES LESS THAN (4, 9),
PARTITION p2 VALUES LESS THAN (4, 11),
PARTITION p3 VALUES LESS THAN (MAXVALUE, MAXVALUE)
);
Performance e Otimização de Banco de Dados MySQL |
24. 24
LIST [COLUMNS]
• Particionamento baseado em valores específicos
• LIST: Uma coluna do tipo INT
○ PARTITION BY LIST( YEAR(matricula) )
• LIST COLUMNS: Múltiplas colunas de vários tipos
○ PARTITION BY LIST COLUMNS ( YEAR(matricula), id_cidade )
Performance e Otimização de Banco de Dados MySQL |
26. 26
LIST
CREATE TABLE `Funcionarios` (
`cpf` VARCHAR(14) NOT NULL,
`nome` VARCHAR(255) NOT NULL,
`filial` INT NOT NULL
)
PARTITION BY LIST(filial) (
PARTITION regiao_norte VALUES IN (1, 2, 7),
PARTITION regiao_sul VALUES IN (3, 9),
PARTITION regiao_leste VALUES IN (4, 5, 6),
PARTITION regiao_oeste VALUES IN (8),
);
Performance e Otimização de Banco de Dados MySQL |
27. 27
LIST COLUMNS
CREATE TABLE `Funcionarios` (
`cpf` VARCHAR(14) NOT NULL,
`estado`VARCHAR(2) NOT NULL DEFAULT 'RS'
)
PARTITION BY LIST COLUMNS (estado) (
PARTITION regiao_sul VALUES IN ('RS', 'SC, 'PR'),
PARTITION regiao_sudeste VALUES IN ('SP', 'RJ', 'MG', 'ES'),
PARTITION regiao_centro_oeste VALUES IN ('MT', 'MS', 'GO', 'DF'),
PARTITION regiao_norte VALUES IN ('AC', 'AM', 'RO', 'RR', 'PA', 'AP', 'TO'),
PARTITION regiao_nordeste VALUES IN ('MA', 'PI', 'CE', 'RN', 'PB', 'PE', 'AL', 'SE', 'BA')
);
Performance e Otimização de Banco de Dados MySQL |
28. 28
[LINEAR] HASH
• Particionamento baseado em cálculo de resto
○ p = MOD(column, n)
○ p - Partição onde a linha é armazenada
○ MOD - função módulo (resto da divisão)
○ column - valor da coluna do tipo INT (numerador)
○ n - número de partições da tabela (denominador)
• PARTITION BY HASH ( YEAR(matricula) )
• LINEAR - Muda o cálculo de módulo para outro baseado em potências
de 2
Performance e Otimização de Banco de Dados MySQL |
29. 29
Pedidos
------------
id
id_cliente
valor
descrição
p0 (resto 0)
-----------------
id
id_cliente
valor
descrição
p1 (resto 1)
-----------------
id
id_cliente
valor
descrição
p2 (resto 2)
-----------------
id
id_cliente
valor
descrição
p3 (resto 3)
-----------------
id
id_cliente
valor
descrição
0,4,8,12,16,... 1,5,9,13,17,... 2,6,10,14,18,... 3,7,11,15,19,...
Resto da divisão de id cliente pelo número de partições
Performance e Otimização de Banco de Dados MySQL |
30. 30
[LINEAR] HASH
CREATE TABLE `Pedidos` (
`id`NOT NULL AUTO_INCREMENT,
`id_cliente` INT NOT NULL,
`valor` DECIMAL(5, 2) NOT NULL,
`descricao` VARCHAR(255) NOT NULL
)
PARTITION BY HASH (id_cliente)
PARTITIONS 4;
Performance e Otimização de Banco de Dados MySQL |
31. 31
[LINEAR] KEY
• A expressão de particionamento pode ser zero ou mais colunas,
conforme segue:
• Se não é especificada coluna
○ Chave primária (se houver)
○ Chave única (se houver)
• Se são especificadas colunas
○ Precisam pertencer à chave primária ou chave única
Performance e Otimização de Banco de Dados MySQL |
32. 32
[LINEAR] KEY
CREATE TABLE k1 (
id INT NOT NULL,
name VARCHAR(20),
PRIMARY KEY (id)
)
PARTITION BY KEY()
PARTITIONS 2;
Performance e Otimização de Banco de Dados MySQL |
33. 33
Subparticionamento
• Particionam-se as partições
• Para utilizar, seguir duas restrições
○ O tipo de partitionamento (PARTITION) precisa ser dos tipos
RANGE ou LIST
○ O tipo de subparticionamento (SUBPARTITION) precisa ser dos
tipos HASH ou KEY
• Portanto, não se pode subparticionar uma tabela particionada por HASH
ou KEY
Performance e Otimização de Banco de Dados MySQL |
34. 34
Cartas
--------
id
id_malote
endereço
enviado
Cartas_a_enviar
-------------------
id
id_malote
endereço
enviado
Cartas_enviadas
-------------------
id
id_malote
endereço
enviado
Particionamento por enviado
0 1
Cartas_a_enviar_0
---------------------
id
id_malote
endereço
enviado
Subparticionamento por id_malote
(resto da divisão de id_malote por 512)
Cartas_a_enviar_1
---------------------
id
id_malote
endereço
enviado
Cartas_enviadas_0
---------------------
id
id_malote
endereço
enviado
Cartas_enviadas_1
---------------------
id
id_malote
endereço
enviado
Cartas_a_enviar_2
---------------------
id
id_malote
endereço
enviado
Cartas_a_enviar_3
---------------------
id
id_malote
endereço
enviado
Cartas_enviadas_2
---------------------
id
id_malote
endereço
enviado
Cartas_enviadas_3
---------------------
id
id_malote
endereço
enviado
Cartas_a_enviar_510
---------------------
id
id_malote
endereço
enviado
Cartas_a_enviar_511
---------------------
id
id_malote
endereço
enviado
Cartas_enviadas_510
---------------------
id
id_malote
endereço
enviado
Cartas_enviadas_511
---------------------
id
id_malote
endereço
enviado
... ...
Performance e Otimização de Banco de Dados MySQL |
35. 35
Subparticionamento
CREATE TABLE `Cartas` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`id_malote` int(11) NOT NULL,
`endereco` varchar(100) NOT NULL,
`enviado` TINYINY(1) NOT NULL DEFAULT 0,
PRIMARY KEY (`id`,`enviado`,`id_malote`),
) ENGINE=InnoDB
PARTITION BY LIST (enviado)
SUBPARTITION BY HASH (id_malote)
SUBPARTITIONS 512
(
PARTITION Cartas_a_enviar VALUES IN (0),
PARTITION Cartas_enviadas VALUES IN (1)
);
Performance e Otimização de Banco de Dados MySQL |
36. 3. Otimização de Consultas
36
O que fazer para que sua consulta seja mais rápida
Performance e Otimização de Banco de Dados MySQL |
37. 37
Índices x Consultas
• Os índices devem corresponder à maioria das consultas executadas em
um sistema, e vice-versa
Performance e Otimização de Banco de Dados MySQL |
38. 38
O que DEVE ser indexado?
• Devem ser indexados campos utilizados frequentemente em consultas
○ Cláusula WHERE
SELECT * FROM Clientes WHERE cidade = ‘Porto Alegre’
○ Colunas de junção em JOINS
SELECT p.numero_pedido, c.nome FROM Pedidos AS p
JOIN Clientes AS c
ON p.cpf_cliente = c.cpf
WHERE p.estado = ‘fechado’
Performance e Otimização de Banco de Dados MySQL |
39. 39
O que DEVE ser indexado?
• Devem ser indexados campos utilizados frequentemente em consultas
○ Colunas usadas em buscas por MIN ou MAX
SELECT MAX(valor) FROM Dividas
○ Colunas utilizadas para GROUP BY ou ORDER BY
SELECT MAX(valor) FROM Dividas
GROUP BY id_cliente
ORDER BY data_criacao
Performance e Otimização de Banco de Dados MySQL |
40. 40
O que DEVE ser indexado?
• Use o menor tipo de dados possível para uma coluna
○ Utiliza menos espaço em disco e em memória
○ Gera índices menores
○ Possibilidade carregar mais dados em cache
○ SELECT * FROM `tabela` PROCEDURE ANALYSE ( )
• Crie índices parciais para texto
○ Utilize no índice o número de caracteres necessários à criação de
uma cardinalidade razoavelmente alta
Performance e Otimização de Banco de Dados MySQL |
41. 41
O que DEVE ser indexado?
• Valha-se dos índices compostos
○ Um índice composto por
i. cpf ASC
ii. data_nascimento ASC
iii. valor_divida ASC
○ Vale para consultas
i. … WHERE cpf = ‘012.345.678-90’
ii. … WHERE cpf = ‘012.345.678-90’ AND data_nascimento > ‘1985-11-18’
iii. … WHERE cpf = ‘012.345.678-90’ AND data_nascimento > ‘1985-11-18’ AND valor_divida >
250.00
Performance e Otimização de Banco de Dados MySQL |
42. 42
O que DEVE ser indexado?
• Valha-se dos índices compostos
○ Um índice composto por
i. cpf ASC
ii. data_nascimento ASC
iii. valor_divida ASC
○ Não vale para consultas
i. … WHERE data_nascimento > ‘1985-11-18’
ii. … WHERE valor_divida > 250.00
iii. … WHERE data_nascimento > ‘1985-11-18’ AND valor_divida > 250.00
Performance e Otimização de Banco de Dados MySQL |
43. 43
O que NÃO DEVE ser indexado?
• Evitar indexar
○ Colunas que só são usadas para exibição
○ Colunas com pouca variação de valor
■ Ex.: CPF é um bom candidato (um por pessoa, muitos valores
possíveis), Gênero é um mau candidato (poucos valores
possíveis: M, F, Outro, Não Informado)
■ Quanto mais valores possíveis, maior a cardinalidade do
índice, e maior sua valia
■ Se a cardinalidade é baixa, o MySQL pode optar por full-scan
Performance e Otimização de Banco de Dados MySQL |
44. 44
Particionamento x Consultas
• Ao utilizar particionamento, TODAS as consultas devem especificar o
valor da(s) coluna(s) utilizada(s) na expressão de particionamento
• Caso não especifiquem, o MySQL realizará full-scan em TODAS as
partições, o que terá desempenho pior do que um full-scan em tabela
não-particionada
Performance e Otimização de Banco de Dados MySQL |
45. 45
Joins
• Evite joins desnecessários, pois são produtos cartesianos
• Caso sejam necessários, crie índices para facilitar a junção
Performance e Otimização de Banco de Dados MySQL |
46. 46
Explain
• Utilize o comando EXPLAIN para saber como uma consulta é executada
EXPLAIN SELECT * FROM Clientes WHERE cidade = ‘Porto Alegre’
• Exibe os índices possíveis, e quais os utilizados
○ Nenhum índice é utilizado? Talvez seja a hora de criar um!
• Se possível, evite buscas cujo explain mostre “using temporary” e/ou
“using filesort”
Performance e Otimização de Banco de Dados MySQL |
47. 47
Explain Partitions
• Utilize o comando EXPLAIN PARTITIONS para saber se sua consulta
utiliza apenas as partições necessárias
EXPLAIN PARTITIONS SELECT * FROM Clientes WHERE cidade = ‘Porto Alegre’
• Se a busca envolve muitas partições, revise seu SELECT para que
especifique melhor os valores possíveis da(s) coluna(s) de
particionamento
Performance e Otimização de Banco de Dados MySQL |
49. 49
Infraestrutura
• Separe seu servidor de banco de dados do servidor de aplicação.
Performance e Otimização de Banco de Dados MySQL |
50. 50
Infraestrutura
• SSD
● Processo de desde 2010
● Atualmente 100% dos servidores de banco está usando discos SSD
Performance e Otimização de Banco de Dados MySQL |
51. 51
Infraestrutura
• Rede dedicada
○ Dedicada para conexão com Banco de Dados
○ Resolução de DNS para rede interna
Performance e Otimização de Banco de Dados MySQL |
53. 53
Painel de controle KingHost
Você é beta! =)
Para testar a ferramenta de Monitoramento de Consumo em seu
Painel de Controle KingHost solicite via chamado informando que você
participou do Webinar!
Importante: no momento, a funcionalidade está disponível apenas
para servidores Linux.
Performance e Otimização de Banco de Dados MySQL |