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

É melhor filtrar um conjunto de resultados usando uma cláusula WHERE ou usando o código do aplicativo?


A regra geral para qualquer aplicativo é deixar o banco de dados fazer o que faz bem:filtrar, classificar e unir.

Separe as consultas em suas próprias funções ou métodos de classe:
$men = $foo->fetchMaleUsers();
$women = $foo->fetchFemaleUsers();

Atualizar


Peguei a demonstração do PostgreSQL de Steven de uma consulta de verificação de tabela completa com desempenho duas vezes melhor do que duas consultas indexadas separadas e a imitei usando o MySQL (que é usado na pergunta real):

Esquema

CREATE TABLE `gender_test` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `gender` enum('male','female') NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=26017396 DEFAULT CHARSET=utf8

Mudei o tipo de gênero para não ser um VARCHAR(20), pois é mais realista para o propósito desta coluna, também forneço uma chave primária como você esperaria em uma tabela em vez de um valor DOUBLE arbitrário.

Resultados não indexados

mysql> select sql_no_cache * from gender_test WHERE gender = 'male';

12995993 rows in set (31.72 sec)

mysql> select sql_no_cache * from gender_test WHERE gender = 'female';

13004007 rows in set (31.52 sec)

mysql> select sql_no_cache * from gender_test;

26000000 rows in set (32.95 sec)

Acredito que isso não precisa de explicação.

Resultados Indexados

ALTER TABLE gender_test ADD INDEX (gender);

...
mysql> select sql_no_cache * from gender_test WHERE gender = 'male';

12995993 rows in set (15.97 sec)

mysql> select sql_no_cache * from gender_test WHERE gender = 'female';

13004007 rows in set (15.65 sec)

mysql> select sql_no_cache * from gender_test;

26000000 rows in set (27.80 sec)

Os resultados mostrados aqui são radicalmente diferente dos dados de Steven. As consultas indexadas têm desempenho quase duas vezes mais rápido que a varredura completa da tabela. Isso é de uma tabela indexada corretamente usando definições de coluna de bom senso. Eu não conheço o PostgreSQL, mas deve haver alguma configuração incorreta significativa no exemplo de Steven para não mostrar resultados semelhantes.

Dada a reputação do PostgreSQL de fazer as coisas melhor que o MySQL, ou pelo menos tão bom quanto, ouso dizer que o PostgreSql demonstraria desempenho semelhante se usado corretamente.

Observe também que, nessa mesma máquina, um loop for excessivamente simplificado fazendo 52 milhões de comparações leva 7,3 segundos adicionais executar.
<?php
$N = 52000000;
for($i = 0; $i < $N; $i++) {
    if (true == true) {
    }
}

Eu acho que é bastante óbvio qual é a melhor abordagem com base nesses dados.