sql >> Base de Datos >  >> RDS >> Mysql

¿Es mejor filtrar un conjunto de resultados usando una cláusula WHERE o usando el código de la aplicación?

La regla general para cualquier aplicación es dejar que la base de datos haga las cosas que hace bien:filtrar, ordenar y unir.

Separe las consultas en sus propias funciones o métodos de clase:

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

Actualizar

Tomé la demostración de PostgreSQL de Steven de una consulta de escaneo de tabla completa que funciona dos veces mejor que dos consultas indexadas separadas y la imité usando MySQL (que se usa en la pregunta 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

Cambié el tipo de género para que no sea un VARCHAR(20) ya que es más realista para el propósito de esta columna. También proporcioné una clave principal como cabría esperar en una tabla en lugar de un valor DOUBLE arbitrario.

Resultados no 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)

Confío en que esto no necesita explicación.

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)

Los resultados que se muestran aquí son radicalmente diferente de los datos de Steven. Las consultas indexadas realizan casi el doble de rápido que el escaneo completo de la tabla. Esto es de una tabla correctamente indexada usando definiciones de columna de sentido común. No conozco PostgreSQL en absoluto, pero debe haber algún error de configuración significativo en el ejemplo de Steven para no mostrar resultados similares.

Dada la reputación de PostgreSQL de hacer las cosas mejor que MySQL, o al menos tan bien como, me atrevo a decir que PostgreSql demostraría un rendimiento similar si se usa correctamente.

También tenga en cuenta que en esta misma máquina, un bucle for demasiado simplificado que realiza 52 millones de comparaciones requiere 7,3 segundos adicionales. para ejecutar.

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

Creo que es bastante obvio cuál es el mejor enfoque dados estos datos.