Workshop Buscapé
    MySQL

  WAGNER BONFIGLIO
      NAVEGG




      Dez/2011
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.
MySQL

Agenda

 Storage Engine
 Comandos
 Índices
 Dicas
MySQL – Storage Engine

 MyISAM
 InnoDB
 BLACKHOLE
 MEMORY
 FEDERATED
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
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
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
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';
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"
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)
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"
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
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
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
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'
MySQL – Comandos

EXPLAIN
 Te diz se a query está usando índice ou não, quantas
  linhas foram scaneadas para achar o resultado, etc
MySQL – Comandos

Profiling
 Mostra quanto demorou uma query e onde esse
  tempo foi gasto. Para habilitar "SET profilling=1;"
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
MySQL - Índice
MySQL - Índice
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!
MySQL




Obrigado!

  Wagner Bonfiglio
bonfiglio@navegg.com

MySQL - Workshop Buscapé

  • 1.
    Workshop Buscapé MySQL WAGNER BONFIGLIO NAVEGG Dez/2011
  • 2.
    Navegg  Maior empresabrasileira 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.
  • 3.
    MySQL Agenda  Storage Engine Comandos  Índices  Dicas
  • 4.
    MySQL – StorageEngine  MyISAM  InnoDB  BLACKHOLE  MEMORY  FEDERATED
  • 5.
    MySQL – StorageEngine 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 – StorageEngine 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 – StorageEngine 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 – StorageEngine 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
  • 19.
  • 20.
  • 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!
  • 22.
    MySQL Obrigado! WagnerBonfiglio bonfiglio@navegg.com