Como o MariaDB Otimiza Cláusulas WHERE
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 MariaDB faz várias otimizações e ainda não tivemos tempo para documentarmos todas elas.
Algumas das otimizações feitas pelo MariaDB 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 umWHERE
é recuperado diretamente da informação da tabela dos tiposMyISAM
eHEAP
. Isto também é feito para qualquer expressãoNOT NULL
quando usada somente com uma tabela.- Pré detecção de expressões contantes inválidas. O MariaDB detecta rapidamente que algumas instruções
SELECT
são impossíveis e não retornará registros. HAVING
é fundido comWHERE
se não for utilizadoGROUP 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 deWHERE
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 índiceUNIQUE
, ou umaPRIMARY KEY
, onde todas as partes do índice são usadas com expressões constantes e as partes do índice são definidas comoNOT 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 emGROUP BY
vierem da mesma tabela, então esta tabela será preferencialmente a primeira na união. - Se existerem uma cláusula
ORDER BY
e umaGROUP BY
diferente, ou se aORDER BY
ouGROUP 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 MariaDB 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 MariaDB 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: