Melhorando o desempenho de suas consultas no MySql

6,852 views
6,586 views

Published on

Material pertencente ao mini-curso sobre MySQL aos desenvolvedores da Hipcom Informática.

Published in: Education
0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
6,852
On SlideShare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
150
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide

Melhorando o desempenho de suas consultas no MySql

  1. 1. Melhorando odesempenho desuas consultasno MySQLComo não aborrecer o DBA e ter um bomdesempenho em suas consultas.
  2. 2. É necessária a otimização?Grande parte da responsabilidade para que obanco de dados funcione bem é de quemmodela a base de dados! Uma Base de dados bem modelada é uma base importante para se criar sistemas coesos e robustos! FreeDigitalPhotos.net
  3. 3. É necessária a otimização?Mas em alguns sistemas, temos umamodelagem muito particular... Nem sempre temos uma base de dados modelada como sonhamos... FreeDigitalPhotos.net
  4. 4. É necessária a otimização?Nestes casos, a otimização deve serprimordial!"Não posso escolher como me sinto, mas posso escolher o que fazer a respeito". William Shakespeare FreeDigitalPhotos.net
  5. 5. Entendendo o banco de dadosrelacionalResumidamente, existem duas maneiras de setrabalhar com um banco de dados relacional... FreeDigitalPhotos.net FreeDigitalPhotos.net Você é livre para escolher qual utilizar! "Não é livre quem não obteve domínio sobre si".Pitágoras
  6. 6. Entendendo o banco de dadosrelacionalBanco de dados relacionais são matemáticos.Eles trabalham, resumidamente, com teoriade conjuntos...● Produto cartesiano● Cardinalidade FreeDigitalPhotos.net "A matemática é o alfabeto com o qual Deus escreveu o universo". Pitágoras
  7. 7. Ferramentas úteis de análisePodemos analisar uma função explícita,utilizando o BENCHMARK.SELECT BENCHMARK(1000000,2+2);O MySQL irá executar um milhão de vezes aexpressão, em determinado tempo.
  8. 8. Ferramentas úteis de análisePodemos entender melhor o funcionamentode nosso script usando o EXPLAIN.EXPLAIN SELECT * FROM ctbplc;O MySQL retornará um registro contendouma análise do script.
  9. 9. Ferramentas úteis de análise● Colunas de retorno do EXPLAIN SELECT ○ ID: Número sequencial que identifica as consultas dentro do SELECT. ○ SELECT_TYPE: Tipo de cláuso SQL: ■ SIMPLE (Select simples) ■ PRIMARY (Select mais externa) ■ UNION (segunda select ou select proveniente do UNION) ■ DEPENDENT UNION (segunda select ou select proveniente do UNION) ■ SUBQUERY (primeiro select encadeado - subquery) ■ DEPENDENT SUBQUERY (primeiro select encadeado da subquery) ■ DERIVED (select de tabela derivada - Subquery da cláusula FROM)
  10. 10. Ferramentas úteis de análise● Colunas de retorno do EXPLAIN SELECT ○ TABLE: Tabela do registro de saída. ○ TYPE: Tipo de JOIN: ■ SYSTEM (tabela que só tem uma linha, tabela de sistema) ■ CONST (tabela que tem no máximo uma linha coincidente. São constantes) ■ EQ_REF (todas as partes da chaves são usadas para combinação de registros) ■ REF (idem ao EQ_REF, mas com índices não únicos) ■ REF_OR_NULL (idem ao REF, mas com busca IS NULL) ■ RANGE (faixa de busca quando o campo é comparado a uma constante) ■ INDEX (quando a consulta só usa colunas que são parte de um índice) ■ ALL (varredura completa na tabela para a busca de registros)
  11. 11. Ferramentas úteis de análise● Colunas de retorno do EXPLAIN SELECT ○ POSSIBLE_KEYS: Sugestão de índices a serem utilizados. ○ KEY: Chave que está sendo utilizado na consulta. ○ KEY_LEN: Tamanho da chave do campo KEY. ○ REF: Colunas utilizadas pela chave do campo KEY. ○ ROWS: Quantidade de linhas que será analisada para gerar a consulta.
  12. 12. Ferramentas úteis de análise● Colunas de retorno do EXPLAIN SELECT ○ EXTRA: Sugestão de índices a serem utilizados. ■ Distinct (Termina a busca quando encontra o primeiro registro coincidente) ■ Not exists (idem ao Distinct, mas com LEFT JOIN) ■ Range checked for each record (index map: #) (O MySQL não encontrou um bom índice para usar) ■ Using filesort (Pesquisa extra na tabela para realizar a ordem de classificação) ■ Using index (Recuperação feita apenas com índices) ■ Using temporary (Utilização de tabelas temporárias para realizar a busca) ■ Using where (Tipo de restrição na busca de registros)Detalhes: http://dev.mysql.com/doc/refman/5.1/en/explain-output.html
  13. 13. Melhorando a performance● Dicas importantes para SELECT a que já existem: ○ ANALYZE TABLE: Esta função atualizará as estatísticas sobre a tabela. Tais estatísticas são utilizadas pelo MYSQL para seleção de como e qual índice pode ser utilizado. ● Utilize SHOW INDEX FROM para verificar se a referência de cardinalidade (coluna Cardinality) está atualizada! ● Os campos das chaves utilizadas devem ser do mesmo tipo e tamanho para que as buscas sejam mais rápidas (também influencia no Join).
  14. 14. Melhorando a performance● Dicas importantes para WHERE: ○ ANALYZE TABLE: Esta função atualizará as estatísticas sobre a tabela. Tais estatísticas são utilizadas pelo MYSQL para seleção de como e qual índice pode ser utilizado. ○ Se todas colunas usadas do índice são numéricas, então somente a árvore de índice é usada para resolver a consulta.
  15. 15. Melhorando a performance● Dicas importantes para WHERE: ○ Se você não utiliza colunas de todas tabelas usadas, o MySQL irá parar a varredura das tabelas não usadas logo que encontrar a primeira coincidência. SELECT DISTINCT t1.a FROM t1,t2 WHERE t1.a=t2.a;
  16. 16. Melhorando a performance● Dicas importantes para WHERE: ○ Você está unindo muitas tabelas e as colunas nas quais você está fazendo um ORDER BY não são todas da primeira tabela que não é constante. ○ O ideal é que os campos do ORDER BY sejam da primeira tabela.
  17. 17. Melhorando a performance● Dica importante para WHERE: ○ Tente usar campos no ORDER BY façam parte de índices. Isso evita um processo de ordenação por parte do MySQL. ○ Internamente, o MySQL ordena as consultas GROUP BY como de fosse o ORDER BY. Para que só o agrupamento aconteça, inclua no seu script um ORDER BY NULL;
  18. 18. Melhorando a performance● Dica importante para LIMIT: ○ O MySQL vai buscar a quantidade de registros estipulados no LIMIT e só depois vai executar outras funções (ORDER BY ou GROUP BY, por exemplo).
  19. 19. Melhorando a performance● Dicas importantes para INSERT: ○ Importação de dados: Pode-de utilizar o LOAD DATA INFILE. A velocidade de inserção de registros pode melhorar em até 20x. ZQuery.Close; ZQuery.SQL.Clear; ZQuery.SQL.Text:=LOAD DATA INFILE c:ctbplc.csv INTO TABLE ctbplc FIELDS TERMINATED BY , ENCLOSED BY "LINES TERMINATED BY nignore 1 lines;; ZQuery.ExecSQL;
  20. 20. Melhorando a performance● Dicas importantes para INSERT: ○ Na importação de um volume grande de dados, também é válido desabilitar os índices com ALTER TABLE <TABELA> DISABLE/ENABLE KEYS.
  21. 21. Melhorando a performance● Dicas importantes para INSERT: ○ Lotes de inserção: Pode-de utilizar o BEGIN / END / COMMIT para montar um bloco de comandos insert. A vantagem em velocidade se torna interessante com blocos de 1000 registro. ZQuery.Close; ZQuery.SQL.Clear; ZQuery.SQL.Text:=start transaction; ZQuery.ExecSQL; try //Comandos dos inserts ... ZQuery.Close; ZQuery.SQL.Clear; ZQuery.SQL.Text:=commit; ZQuery.ExecSQL; except ZQuery.Close; ZQuery.SQL.Clear; ZQuery.SQL.Text:=rollback; ZQuery.ExecSQL; end;
  22. 22. Melhorando a performance● Dica importante para UPDATE: ○ Deixar para alterar todo o registro de uma só vez.
  23. 23. Melhorando a performance● Dica importante para DELETE: ○ Se for "limpar" uma tabela, use o TRUNCATE TABLE
  24. 24. Melhorando a performance● Dicas importantes: ○ Dentro do possível, dê preferência para a utilização de conexões persistentes. Isso evita sobrecarga de conexões no servidor de banco de dados.
  25. 25. Melhorando a performance● Dicas importantes: ○ Se suas buscas usam uma determinada ordem de campos, mas na tabela esses campos estão em uma ordem diferente, mude a ordem dos campos da tabela com ALTER TABLE... ORDER BY expr1, expr2....
  26. 26. Melhorando a performance● Quebrando alguns paradigmas: ○ Índices com muitos campos podem ser substituidos por um único campo "hash": SELECT * FROM <nome_tabela> WHERE col_hash=MD5(concat (col1,col2)) AND col_1=constante AND col_2=constante.
  27. 27. Melhorando a performance● Quebrando alguns paradigmas: ○ Tabelas com muita alteração: evite as colunas varchar e blob. Dê preferência a registros de tamanho fixo.
  28. 28. Melhorando a performance● Quebrando alguns paradigmas: ○ Não tenha vergonha de quebrar, em pontos críticos, a 3ª forma normal.Mais detalhes: http://pt.wikipedia.org/wiki/Banco_de_dados_relacional
  29. 29. Entendendo melhor as coisas...● Como funcionam os índices? FreeDigitalPhotos.net
  30. 30. Entendendo melhor as coisas...● Onde os índices são usados: ○ Para encontrar rapidamente os registros que coincidam com uma cláusula WHERE. ○ Para recuperar registros de outras tabelas ao realizar joins. ○ Para encontrar o valor MAX() ou MIN() para uma coluna indexada especifica. ○ Para ordenar ou agrupar uma tabela.
  31. 31. Entendendo melhor as coisas...● Exemplos: ○ Se a tabela possuir um índice de múltiplas colunas, qualquer prefixo mais à esquerda do índice pode ser usado pelo MySQL para encontrar registros. Por exemplo, se você possui um índice de três colunas em (col1, col2, col3), você tem capacidades de busca indexada em (col1), (col1, col2) e (col1, col2, col3). ○ SELECT col3 FROM <nome_tabela> WHERE col1=1 . ○ SELECT * FROM <nome_tabela> WHERE col1=val1 AND col2=val2 .
  32. 32. Entendendo melhor as coisas...● Exemplos: ○ Se a tabela possuir um índice de múltiplas colunas, qualquer prefixo mais à esquerda do índice pode ser usado pelo MySQL para encontrar registros. Por exemplo, se você possui um índice de três colunas em (col1, col2, col3), você tem capacidades de busca indexada em (col1), (col1, col2) e (col1, col2, col3). ○ SELECT * FROM <nome_tabela> WHERE col1=val1; ○ SELECT * FROM <nome_tabela> WHERE col2=val2; ○ SELECT * FROM <nome_tabela> WHERE col2=val2 AND col3=val3;
  33. 33. Entendendo melhor as coisas...● Exemplos: CREATE TABLE teste ( id INT NOT NULL, ultimo_nome CHAR(30) NOT NULL, primeiro_nome CHAR(30) NOT NULL, PRIMARY KEY (id), INDEX nome (ultimo_nome,primeiro_nome)); ○ SELECT * FROM teste WHERE ultimo_nome="Lopes"; ○ SELECT * FROM teste WHERE ultimo_nome="Lopes" AND primeiro_nome=" Helder"; ○ SELECT * FROM teste WHERE ultimo_nome="Lopes" AND (primeiro_nome=" Helder" OR primeiro_nome="Francisco"); ○ SELECT * FROM teste WHERE ultimo_nome="Lopes" AND primeiro_nome >=" H" AND primeiro_nome < "S"; ○ SELECT * FROM teste WHERE primeiro_nome="Helder"; ○ SELECT * FROM teste WHERE ultimo_nome="Lopes" OR primeiro_nome=" Helder";
  34. 34. Entendendo melhor as coisas...● Exemplos: ○ Um índice é usado para colunas que você compara com os seguintes operadores: =, >, >=, <, <=, BETWEEN, IS NULL ou um LIKE com um padrão que começa com um prefixo sem meta caracteres. ○ SELECT * FROM <nome_tabela> WHERE key_col LIKE "Helder%"; ○ SELECT * FROM <nome_tabela> WHERE key_col LIKE "Hel%_er%" ○ SELECT * FROM <nome_tabela> WHERE key_col LIKE "%Helder%";
  35. 35. Entendendo melhor as coisas...● Cuidado com os AND: ○ Qualquer índice que não cobre todos os níveis de AND na cláusula WHERE não é utilizado para otimizar a consulta.
  36. 36. Entendendo melhor as coisas...● Índices pré-fixados: ○ Para colunas CHAR, VARCHAR, BLOB e TEXT pode- se indexar um prefixo da coluna. ○ Isto é muito mais rápido e necessita de menos espaço em disco do que indexar a coluna inteira. CREATE TABLE teste ( nome CHAR(200) NOT NULL, INDEX nome_indice (nome(10)) );
  37. 37. Bibliografia● Baron Schwartz, Peter Zaitsev, Vadim Tkachenko, Jeremy D. Zawodny, Arjen Lentz, Derek J. Balling. High Performance MySQL: Optimization, Backups, Replication, and More. OReilly Media, Inc., 2008; 2ª ed; ISBN 0596554753.● Wikipédia. Árvore B. http://pt.wikipedia.org/wiki/%C3%81rvore_B Acessado em 18/02/2013.

×