Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Como otimizar consultas em um banco de dados - O básico


Você tem que fazer uma busca para cada condição where e para cada junção... na condição. Os dois funcionam da mesma forma.

Suponha que escrevemos
select name
from customer
where customerid=37;

De alguma forma, o DBMS precisa encontrar o registro ou registros com customerid=37. Se não houver índice, a única maneira de fazer isso é ler todos os registros da tabela comparando o customerid com 37. Mesmo quando encontra um, ele não tem como saber que existe apenas um, portanto, deve continuar procurando outros.

Se você criar um índice em customerid, o DBMS terá maneiras de pesquisar o índice muito rapidamente. Não é uma busca sequencial, mas, dependendo do banco de dados, uma busca binária ou algum outro método eficiente. Exatamente como não importa, aceite que é muito mais rápido que sequencial. O índice então o leva diretamente para o registro ou registros apropriados. Além disso, se você especificar que o índice é "único", o banco de dados saberá que só pode haver um para que não perca tempo procurando um segundo. (E o DBMS impedirá que você adicione um segundo.)

Agora considere esta consulta:
select name
from customer
where city='Albany' and state='NY';

Agora temos duas condições. Se você tiver um índice em apenas um desses campos, o DBMS usará esse índice para localizar um subconjunto dos registros e, em seguida, pesquisá-los sequencialmente. Por exemplo, se você tiver um índice no estado, o DBMS localizará rapidamente o primeiro registro de NY e, em seguida, procurará sequencialmente por city='Albany' e parará de procurar quando atingir o último registro de NY.

Se você tiver um índice que inclua os dois campos, ou seja, "criar índice no cliente (estado, cidade)", o DBMS poderá ampliar imediatamente os registros corretos.

Se você tiver dois índices separados, um em cada campo, o DBMS terá várias regras que serão aplicadas para decidir qual índice usar. Novamente, exatamente como isso é feito depende do DBMS específico que você está usando, mas basicamente ele tenta manter estatísticas sobre o número total de registros, o número de valores diferentes e a distribuição de valores. Em seguida, ele procurará esses registros sequencialmente para aqueles que satisfaçam a outra condição. Nesse caso, o SGBD provavelmente observaria que há muito mais cidades do que estados, portanto, usando o índice de cidades, ele pode ampliar rapidamente os registros 'Albany'. Em seguida, ele irá pesquisá-los sequencialmente, verificando o estado de cada um em relação a 'NY'. Se você tiver registros para Albany, Califórnia, eles serão ignorados.

Cada junção requer algum tipo de pesquisa.

Diga que escrevemos
select customer.name
from transaction
join customer on transaction.customerid=customer.customerid
where transaction.transactiondate='2010-07-04' and customer.type='Q';

Agora o SGBD precisa decidir qual tabela ler primeiro, selecionar os registros apropriados de lá e então encontrar os registros correspondentes na outra tabela.

Se você tivesse um índice em transaction.transactiondate e customer.customerid, o melhor plano provavelmente seria encontrar todas as transações com essa data e, em seguida, para cada uma delas, encontrar o cliente com o customerid correspondente e, em seguida, verificar se o cliente tem o tipo certo.

Se você não tiver um índice em customer.customerid, o DBMS poderá localizar rapidamente a transação, mas, para cada transação, ele terá que pesquisar sequencialmente a tabela de clientes procurando um customerid correspondente. (Isso provavelmente seria muito lento.)

Suponha que os únicos índices que você tem estejam em transaction.customerid e customer.type. Então o DBMS provavelmente usaria um plano completamente diferente. Ele provavelmente examinaria a tabela de clientes em busca de todos os clientes com o tipo correto e, em seguida, para cada um deles, encontraria todas as transações desse cliente e as procuraria sequencialmente pela data correta.

A chave mais importante para a otimização é descobrir quais índices realmente ajudarão e criar esses índices. Índices extras e não utilizados são um fardo para o banco de dados porque dá trabalho mantê-los e, se eles nunca forem usados, isso é um esforço desperdiçado.

Você pode dizer quais índices o DBMS usará para qualquer consulta com o comando EXPLAIN. Eu uso isso o tempo todo para determinar se minhas consultas estão sendo bem otimizadas ou se devo criar índices adicionais. (Leia a documentação sobre este comando para obter uma explicação de sua saída.)

Advertência:Lembre-se que eu disse que o SGBD mantém estatísticas sobre o número de registros e o número de valores diferentes e assim por diante em cada tabela. EXPLAIN pode fornecer um plano completamente diferente hoje do que ontem, se os dados forem alterados. Por exemplo, se você tiver uma consulta que une duas tabelas e uma dessas tabelas for muito pequena enquanto a outra for grande, ela tenderá a ler primeiro a tabela pequena e depois localizar os registros correspondentes na tabela grande. A adição de registros a uma tabela pode alterar o que é maior e, assim, levar o SGBD a alterar seu plano. Assim, você deve tentar fazer EXPLAINS em um banco de dados com dados realistas. A execução em um banco de dados de teste com 5 registros em cada tabela tem muito menos valor do que a execução em um banco de dados ativo.

Bem, há muito mais que poderia ser dito, mas eu não quero escrever um livro aqui.