melhorando o desempenho de suas consultas no mysql

37
Melhorando o desempenho de suas consultas no MySQL Como não aborrecer o DBA e ter um bom desempenho em suas consultas.

Upload: helder-lopes

Post on 24-May-2015

4.602 views

Category:

Education


7 download

DESCRIPTION

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

TRANSCRIPT

Page 1: Melhorando o desempenho de suas consultas no MySql

Melhorando o desempenho de suas consultas no MySQLComo não aborrecer o DBA e ter um bom desempenho em suas consultas.

Page 2: Melhorando o desempenho de suas consultas no MySql

É necessária a otimização?

Grande parte da responsabilidade para que o banco de dados funcione bem é de quem modela a base de dados!

Uma Base de dados bem modelada é uma base importante para

se criar sistemas coesos e robustos!

FreeDigitalPhotos.net

Page 3: Melhorando o desempenho de suas consultas no MySql

É necessária a otimização?

Mas em alguns sistemas, temos uma modelagem muito particular...

Nem sempre temos uma base de dados

modelada como sonhamos...

FreeDigitalPhotos.net

Page 4: Melhorando o desempenho de suas consultas no MySql

É necessária a otimização?

Nestes casos, a otimização deve ser primordial!

"Não posso escolher como me sinto, mas posso escolher o que fazer a respeito".

William Shakespeare

FreeDigitalPhotos.net

Page 5: Melhorando o desempenho de suas consultas no MySql

Entendendo o banco de dados relacional

Resumidamente, existem duas maneiras de se trabalhar com um banco de dados relacional...

Você é livre para escolher qual utilizar!"Não é livre quem não obteve domínio sobre si".Pitágoras

FreeDigitalPhotos.netFreeDigitalPhotos.net

Page 6: Melhorando o desempenho de suas consultas no MySql

Entendendo o banco de dados relacional

Banco de dados relacionais são matemáticos.Eles trabalham, resumidamente, com teoria de conjuntos...● Produto cartesiano● Cardinalidade

"A matemática é o alfabeto com o qual Deus escreveu o universo". Pitágoras

FreeDigitalPhotos.net

Page 7: Melhorando o desempenho de suas consultas no MySql

Ferramentas úteis de análise

Podemos analisar uma função explícita, utilizando o BENCHMARK.

SELECT BENCHMARK(1000000,2+2);

O MySQL irá executar um milhão de vezes a expressão, em determinado tempo.

Page 8: Melhorando o desempenho de suas consultas no MySql

Ferramentas úteis de análise

Podemos entender melhor o funcionamento de nosso script usando o EXPLAIN.

EXPLAIN SELECT * FROM ctbplc;

O MySQL retornará um registro contendo uma análise do script.

Page 9: Melhorando o desempenho de suas consultas no MySql

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)

Page 10: Melhorando o desempenho de suas consultas no MySql

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)

Page 11: Melhorando o desempenho de suas consultas no MySql

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.

Page 12: Melhorando o desempenho de suas consultas no MySql

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

Page 13: Melhorando o desempenho de suas consultas no MySql

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).

Page 14: Melhorando o desempenho de suas consultas no MySql

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.

Page 15: Melhorando o desempenho de suas consultas no MySql

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;

Page 16: Melhorando o desempenho de suas consultas no MySql

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.

Page 17: Melhorando o desempenho de suas consultas no MySql

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;

Page 18: Melhorando o desempenho de suas consultas no MySql

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).

Page 19: Melhorando o desempenho de suas consultas no MySql

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 ''\n''ignore 1 lines;'; ZQuery.ExecSQL;

Page 20: Melhorando o desempenho de suas consultas no MySql

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.

Page 21: Melhorando o desempenho de suas consultas no MySql

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;

Page 22: Melhorando o desempenho de suas consultas no MySql

Melhorando a performance● Dica importante para UPDATE:

○ Deixar para alterar todo o registro de uma só vez.

Page 23: Melhorando o desempenho de suas consultas no MySql

Melhorando a performance● Dica importante para DELETE:

○ Se for "limpar" uma tabela, use o TRUNCATE TABLE

Page 24: Melhorando o desempenho de suas consultas no MySql

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.

Page 25: Melhorando o desempenho de suas consultas no MySql

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....

Page 26: Melhorando o desempenho de suas consultas no MySql

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'.

Page 27: Melhorando o desempenho de suas consultas no MySql

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.

Page 28: Melhorando o desempenho de suas consultas no MySql

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

Page 29: Melhorando o desempenho de suas consultas no MySql

Entendendo melhor as coisas...● Como funcionam os índices?

FreeDigitalPhotos.net

Page 30: Melhorando o desempenho de suas consultas no MySql

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.

Page 31: Melhorando o desempenho de suas consultas no MySql

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 .

Page 32: Melhorando o desempenho de suas consultas no MySql

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;

Page 33: Melhorando o desempenho de suas consultas no MySql

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";

Page 34: Melhorando o desempenho de suas consultas no MySql

Entendendo melhor as coisas...● Exemplos:

○ Um índice é usado para colunas que você compara com os seguintesoperadores: =, >, >=, <, <=, 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%";

Page 35: Melhorando o desempenho de suas consultas no MySql

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.

Page 36: Melhorando o desempenho de suas consultas no MySql

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)));

Page 37: Melhorando o desempenho de suas consultas no MySql

Bibliografia● Baron Schwartz, Peter Zaitsev, Vadim Tkachenko, Jeremy D. Zawodny, Arjen Lentz, Derek J.

Balling. High Performance MySQL: Optimization, Backups, Replication, and More. O'Reilly Media, Inc., 2008; 2ª ed; ISBN 0596554753.

● Wikipédia. Árvore B. http://pt.wikipedia.org/wiki/%C3%81rvore_B Acessado em 18/02/2013.