Mysql
 sql >> Database >  >> RDS >> Mysql

È meglio filtrare un set di risultati utilizzando una clausola WHERE o utilizzando il codice dell'applicazione?

La regola pratica per qualsiasi applicazione è lasciare che il DB faccia le cose che fa bene:filtrare, ordinare e unire.

Separa le query nelle proprie funzioni o metodi di classe:

$men = $foo->fetchMaleUsers();
$women = $foo->fetchFemaleUsers();

Aggiorna

Ho preso la dimostrazione di PostgreSQL di Steven di una query di scansione completa della tabella con prestazioni doppie rispetto a due query indicizzate separate e l'ho imitata usando MySQL (che è usato nella domanda vera e propria):

Schema

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

Ho modificato il tipo di genere in modo che non fosse un VARCHAR(20) poiché è più realistico ai fini di questa colonna, fornisco anche una chiave primaria come ti aspetteresti su una tabella invece di un valore DOUBLE arbitrario.

Risultati non indicizzati

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)

Confido che questo non abbia bisogno di spiegazioni.

Risultati indicizzati

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)

I risultati mostrati qui sono radicalmente diverso dai dati di Steven. Le query indicizzate eseguono quasi due volte più veloce della scansione completa della tabella. Questo proviene da una tabella indicizzata correttamente utilizzando definizioni di colonna di buon senso. Non conosco affatto PostgreSQL, ma ci deve essere qualche errore di configurazione significativo nell'esempio di Steven per non mostrare risultati simili.

Data la reputazione di PostgreSQL di fare le cose meglio di MySQL, o almeno altrettanto bene, oserei dire che PostgreSql dimostrerebbe prestazioni simili se usato correttamente.

Tieni inoltre presente che su questa stessa macchina un ciclo for eccessivamente semplificato che esegue 52 milioni di confronti richiede 7,3 secondi aggiuntivi da eseguire.

<?php
$N = 52000000;
for($i = 0; $i < $N; $i++) {
    if (true == true) {
    }
}

Penso che sia piuttosto ovvio quale sia l'approccio migliore dati questi dati.