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,... ;
This is a translation of the MySQL Reference Manual that can be found at dev.mysql.com. The original Reference Manual is in English, and this translation is not necessarily as up to date as the English version.