
Fala, galera! O papo de hoje é sobre banco de dados, mais especificamente sobre
MySQL, um banco de dados que apesar de free, é bem poderoso, sobretudo pra quem precisa de banco de dados e tem um orçamento apertado. Basta dizer que ele atendeu ao SuperVasco enquanto eu estive à frente do site, que chega a ter 1000 usuários online por minuto várias vezes por dia.
Bom, todo desenvolvedor web já fez uma página de consulta, né? Aquele velho esquema: Lista das ocorrências retornadas, separadas em páginas de, digamos, 20 ocorrências por página e o velho link pra navegar entre as páginas. Na navegação você tem que informar que o usuário está na página 1 de 8. Pra isso, obviamente você vai ter que saber quantos registros no total satisfizeram a condição de busca informada pelo usuário. Quem já mexeu com BD sabe que isso se faz usando um "
s.elect count", certo? Certo, mas no MySQL tem um jeito melhor de fazer. Vamos a um exemplo prático pra facilitar o entendimento:
Se você quer deixar seu usuário pesquisar exatamente pela palavra "intervalado" no seu banco de dados, fará algo como:
"
s.elect datMateria, strTituloMateria, strTextoMateria from matérias where strTextoMateria like ‘%intervalado%’ order by datMateria desc limit 0, 20."
Pra saber quantas ocorrências houve no total, você fará algo como:
"
s.elect count(lngCodMateria) from matérias where strTextoMateria like ‘%intervalado%’"
Qual o problema nessa abordagem? Como você quer que o usuário ache a palavra "intervalado", usará obrigatoriamente a cláusula
like, que varre a tabela de matérias inteira. Duas vezes, como diria Chuck Norris... Uma vez para obter os dados e outra para o total. E isso, pra maior tabela do seu site que é sucesso de crítica e de público como era o SuperVasco, pode ser um desastre em termos de performance. Aí vem a dica de hoje.
O s.elect do MySQL tem uma cláusula
SQL_CALC_FOUND_ROWS, que calcula quantas linhas foram retornadas, independente de você ter usado ou não o "limit". Imediatamente depois deve ser usado o comando "
s.elect FOUND_ROWS()", que aí, sim, retorna o número total de registros retornados, mas sem varrer novamente a tabela! TRUCO!
Não conheço a arquitetura do banco, mas imagino que o MySQL deva acrescentar mais uma coluna "escondida" às retornadas pelo seu s.elect, coluna cujo valor vá ser retornado no s.elect FOUND_ROWS().
Isso, em conjunto com outra cláusula legal do MySQL, o
SQL_CACHE, que eu detalharei em outra ocasião, podem dar uma bela desengargalada nos acessos a banco de dados do seu site.
Como diria meu primo Pernalonga, That´s all, folks! Até a próxima!