:: DEVELOPER ZONE
As otimizações WHERE são colocadas aqui na parte da SELECT porque
normalmente elas são usadas com SELECT, mas as mesmas otimizações
aplicam-se para WHERE em instruções DELETE e UPDATE.
Note também que esta seção está incompleta. O MySQL faz várias otimizações e ainda não tivemos tempo para documentarmos todas elas.
Algumas das otimizações feitas pelo MySQL são são listadas abaixo:
Remoção de parênteses desnecessários:
((a AND b) AND c OR (((a AND b) AND (c AND d)))) -> (a AND b AND c) OR (a AND b AND c AND d)
Enlaços de constantes:
(a<b AND b=c) AND a=5 -> b>5 AND b=c AND a=5
Remoção de condições contantes (necessário por causa dos enlaços de contantes):
(B>=5 AND B=5) OR (B=6 AND 5=5) OR (B=7 AND 5=6) -> B=5 OR B=6
Expressões constantes utilizadas por índices são avaliadas somente uma vez.
COUNT(*) em uma única tabela sem um WHERE é recuperado diretamente
da informação da tabela dos tipos MyISAM e HEAP. Isto também é feito
para qualquer expressão NOT NULL quando usada somente com uma tabela.
Pré detecção de expressões contantes inválidas. O MySQL detecta rapidamente
que algumas instruções SELECT são impossíveis e não retornará registros.
HAVING é fundido com WHERE se não for utilizado GROUP BY
ou funções de agrupamento (COUNT(), MIN()...).
Para cada sub-join, um WHERE mais simples é construído para obter
uma avaliação mais rápida de WHERE para cada sub-join e também para
saltar registros da maneira mais rápida possível.
Todas tabelas constantes são lidas primeiro, antes de qualquer tabelas na consulta. Uma tabela constante é:
Uma tabela vazia ou uma tabela com 1 registro.
Uma tabela que é usada com uma cláusula WHERE em um índice UNIQUE,
ou uma PRIMARY KEY, onde todas as partes do índice são usadas com
expressões constantes e as partes do índice são definidas como NOT NULL.
Todas as tabelas seguintes são usadas como tabelas constantes:
mysql> SELECT * FROM t WHERE primary_key=1;
mysql> SELECT * FROM t1,t2
-> WHERE t1.primary_key=1 AND t2.primary_key=t1.id;
A melhor combinação de join para unir as tabelas é encontrada tentando
todas as possibilidades. Se todas colunas em ORDER BY e em
GROUP BY vierem da mesma tabela, então esta tabela será preferencialmente
a primeira na união.
Se existerem uma cláusula ORDER BY e uma GROUP BY diferente,
ou se a ORDER BY ou GROUP BY conterem colunas
de tabelas diferentes da primeira tabela na fila de join, uma
tabela temporária será criada.
Se você utilizar SQL_SMALL_RESULT, o MySQL usará a tabela temporária
em memória.
Cada índice de tabela é consultado e o melhor índice que cobrir menos de 30% dos registros é usado. Se nenhum índice for encontrado, uma varredura rápida é feita pela tabela.
Em alguns casos, o MySQL pode ler registros do índice mesmo sem consultar o arquivo de dados. Se todas colunas usadas do índice são numéricas, então somente a árvore de índice é usada para resolver a consulta.
Antes de dar saída em cada registro, aqueles que não combinam com a cláusula
HAVING são ignorados.
Some examples of queries that are very fast:
mysql> SELECT COUNT(*) FROM tbl_name;
mysql> SELECT MIN(key_part1),MAX(key_part1) FROM tbl_name;
mysql> SELECT MAX(key_part2) FROM tbl_name
-> WHERE key_part_1=constant;
mysql> SELECT ... FROM tbl_name
-> ORDER BY key_part1,key_part2,... LIMIT 10;
mysql> SELECT ... FROM tbl_name
-> ORDER BY key_part1 DESC,key_part2 DESC,... LIMIT 10;
As seguintes consultas são resolvidas utilizando somente a árvore de índices (assumindo que as colunas indexadas são numéricas):
mysql> SELECT key_part1,key_part2 FROM tbl_name WHERE key_part1=val;
mysql> SELECT COUNT(*) FROM tbl_name
-> WHERE key_part1=val1 AND key_part2=val2;
mysql> SELECT key_part2 FROM tbl_name GROUP BY key_part1;
As consultas a seguir utilizam indexação para recuperar os registros na ordem de classificação sem um passo de ordenação separado:
mysql> SELECT ... FROM tbl_name
-> ORDER BY key_part1,key_part2,... ;
mysql> SELECT ... FROM tbl_name
-> ORDER BY key_part1 DESC,key_part2 DESC,... ;
© 1995-2005 MySQL AB. All rights reserved.
