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 tiposMyISAMeHEAP. Isto também é feito para qualquer expressãoNOT NULLquando usada somente com uma tabela.- Pré detecção de expressões contantes inválidas. O MariaDB detecta rapidamente que algumas instruções
SELECTsão impossíveis e não retornará registros. HAVINGé fundido comWHEREse não for utilizadoGROUP BYou funções de agrupamento (COUNT(),MIN()...).- Para cada sub-join, um
WHEREmais simples é construído para obter uma avaliação mais rápida deWHEREpara 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
WHEREem 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 BYe emGROUP BYvierem da mesma tabela, então esta tabela será preferencialmente a primeira na união. - Se existerem uma cláusula
ORDER BYe umaGROUP BYdiferente, ou se aORDER BYouGROUP BYconterem 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
HAVINGsã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: