O documento apresenta informações sobre o uso do MySQL na Navegg, maior empresa brasileira de segmentação de audiência online. Apresenta detalhes sobre os storage engines MySQL e InnoDB, comandos como INSERT DELAYED e SUBQUERY, e dicas sobre desempenho como usar índices e amostras de dados.
2. Navegg
Maior empresa brasileira de segmentação de audiência online
Fundada em 2009, comprada pelo Buscapé em fev/2011
Analisa mais de 4 bilhões de visitas por mês
Mais de 80 milhões de internautas analisados
Linguagens C, Python e PHP
Bancos de dados MySQL, Redis e MongoDB
Ambiente Linux.
5. MySQL – Storage Engine
MyISAM InnoDB
Não suporta transações Aceita a transações
Não suporta FK Aceita PK
Lock a nível de tabelas Lock a nível de registro
Cache de índice Cache de índice e dados
Ruim para escrita Otimizado para escrita
concorrente concorrente
Otimizado para leitura Não é otimizado para
muitas leituras
6. MySQL – Storage Engine
BLACKHOLE
Não grava nada na tabela, apenas no Log Binário
Aceita transação
Não aceita AUTO_INCREMENT e DELAYED
Usado para:
Log
Enviar dados para servidor de processamento
7. MySQL – Storage Engine
MEMORY / HEAP
Dados ficam apenas em memória e são perdidos em
caso de crash do MySQL
Tabelas devem caber em memória para evitar SWAP
(max_heap_table_size)
Aceita índice e AUTO_INCREMENT
Não aceita TEXT e BLOB
Usado como cópia de tabelas muito acessadas, dados
perecíveis ou cache
8. MySQL – Storage Engine
FEDERATED
Link para tabelas em outras máquinas / instâncias
CREATE TABLE tabela (
id int(10), name varchar(100)
) ENGINE=FEDERATED
CONNECTION='mysql://user@remote_host:3610/
mydatabase/test_table';
9. MySQL – Comandos
INSERT DELAYED
Libera a sessão na hora e deixa o INSERT na fila para
ser inserido em lotes
HAVING
Após feitos todos os cálculos da query como COUNT
ou SUM, podemos filtrar apenas resultados "HAVING
COUNT(col) > 10" ou "HAVING SUM(col) > 100"
10. MySQL – Comandos
REPLACE
Funciona igual o INSERT, mas caso já exista uma
linha com a mesma PK ou UK esta linha é apagada e a
nova é colocada em seu lugar (funcionando como um
UPDATE)
11. MySQL – Comandos
Tipo de dado SET e ENUM
name ENUM('small','medium','large')
1 - small, 2 - medium, 3 - large
col SET('a','b')
aceita "","a","b","a,b"
12. MySQL – Comandos
Subquery
SELECT * FROM PROFILE WHERE ID IN (SELECT
ID FROM PROFILESTATUS)
SELECT * FROM (SELECT ID, GENDER, AGE FROM
PROFILE WHERE EDUCATION=3) pro, (SELECT
PROFILE, SITE FROM VISIT WHERE DATE='2011-
12-06') vis WHERE pro.ID=vis.PROFILE
13. MySQL – Comandos
Subquery
SELECT * FROM PROFILE WHERE ID IN (SELECT
ID FROM PROFILESTATUS)
SELECT * FROM (SELECT ID, GENDER, AGE FROM
PROFILE WHERE EDUCATION=3) pro, (SELECT
PROFILE, SITE FROM VISIT WHERE DATE='2011-
12-06') vis WHERE pro.ID=vis.PROFILE
14. MySQL – Comandos
Subquery
SELECT * FROM PROFILE WHERE ID IN (SELECT
ID FROM PROFILESTATUS)
SELECT * FROM PROFILE p, PROFILESTATUS s WHERE p.ID=s.ID
SELECT * FROM (SELECT ID, GENDER, AGE FROM
PROFILE WHERE EDUCATION=3) pro, (SELECT
PROFILE, SITE FROM VISIT WHERE DATE='2011-
12-06') vis WHERE pro.ID=vis.PROFILE
15. MySQL – Comandos
Subquery
SELECT * FROM PROFILE WHERE ID IN (SELECT
ID FROM PROFILESTATUS)
SELECT * FROM PROFILE p, PROFILESTATUS s WHERE p.ID=s.ID
SELECT * FROM (SELECT ID, GENDER, AGE FROM
PROFILE WHERE EDUCATION=3) pro, (SELECT
PROFILE, SITE FROM VISIT WHERE DATE='2011-
12-06') vis WHERE pro.ID=vis.PROFILE
SELECT * FROM PROFILE pro,VISIT vis WHERE pro.ID=vis.PROFILE
AND pro.EDUCATION=3 AND vis.DATE='2011-12-06'
16. MySQL – Comandos
EXPLAIN
Te diz se a query está usando índice ou não, quantas
linhas foram scaneadas para achar o resultado, etc
17. MySQL – Comandos
Profiling
Mostra quanto demorou uma query e onde esse
tempo foi gasto. Para habilitar "SET profilling=1;"
18. MySQL - Índice
Entenda como o MySQL usa índices
http://dev.mysql.com/doc/refman/5.1/en/mysql-indexes.html
Use o EXPLAIN para saber se os seus índices são
usados nas suas queries
21. MySQL - Dicas
Pool (disco)
Separar tabelas em databases distintos via código e usar o SO para separá-las em
discos diferentes
Não usar UPDATE/DELETE
Para evitar muitos UPDATEs e/ou DELETEs é melhor criar uma tabela
temporária e dar um truncate no final
Amostras
Dependendo o tipo de dados a serem calculados, uma amostra de 1% ou 10%
pode ser suficiente (evitar para cálculos que envolvem $$$)
Monte seu índice
JOIN com uma coluna de 4 caracteres é mais barato que uma coluna VARCHAR
Normalize no Back End mas não ligue para redundância no Front
No Front vale a pena manter os dados prontos para evitar JOIN
TUNING + TUNING + TUNING
Entenda as configurações de cache e memória e faça seu tuning!
Replicação / Cluster
Cluster no MYSQL não performa bem, já a replicação pode ser uma boa aliada!