Pregunta

Necesito consejos sobre el rendimiento de la subselección en MySQL. Por una razón que no puedo cambiar, no puedo usar JOIN para crear un filtro de preguntas, solo puedo agregar otra cláusula AND en WHERE.

¿Cuál es el rendimiento de:

select tasks.*
from tasks
where 
  some criteria
  and task.project_id not in (select id from project where project.is_template = 1);

en comparación con:

select tasks.*
from tasks, project
where
  some criteria
  and task.project_id = project.id and project.is_template <> 1;

Tenga en cuenta que hay un número relativamente pequeño de proyectos donde is_template = 1, y podría haber un gran número de proyectos donde is_template < > 1.

¿Hay otra manera de lograr el mismo resultado sin subselecciones si no puedo cambiar nada más que filtrar?

¿Fue útil?

Solución

Creo que el segundo es más eficiente ya que solo requiere una selección, pero para estar seguro, debe EXPLICAR cada consulta y verificar los resultados.

EXPLAIN select tasks.*
from tasks
where 
  some criteria
  and task.project_id not in (select id from project where project.is_template = 1);

EXPLAIN select tasks.*
from tasks, project
where
  some criteria
  and task.project_id = project.id and project.is_template <> 1;

Otros consejos

¿Cuánta diferencia hay entre los dos podría depender en gran medida de lo que & "; algunos criterios &"; es y qué oportunidades de usar índices proporciona. Pero tenga en cuenta que no son equivalentes en términos de resultados si hay tareas que no tienen proyectos. El segundo es equivalente a esto:

select tasks.*
from tasks
where 
  some criteria
  and task.project_id in (select id from project where project.is_template <> 1);

Creo que el primero puede escalar mejor:

Cuando realiza una unión, internamente mysql crea una especie de tabla temporal que consta de las dos tablas unidas de acuerdo con las condiciones de unión especificadas. No está dando una condición de unión, por lo que creará una tabla temporal con todas las tareas enumeradas en todos los proyectos. Estoy bastante seguro (pero verifique con la herramienta de explicación) que lo hace antes de aplicar las cláusulas where.

Resultado: si hay 10 de cada uno, tendrá 10 * 10 filas = 100. Puede ver cómo esto aumenta a medida que aumentan los números. Luego aplica el where a esta tabla temporal.

Por el contrario, la subconsulta selecciona solo las filas relevantes de cada tabla.

Pero a menos que la escala sea una preocupación, no creo que realmente importe.

Evite subconsultas como la peste en las versiones de MySQL < 6.0, y dudo que esté usando 6.0 teniendo en cuenta que todavía está en la fase alfa de desarrollo. AFAIK, el optimizador MySQL no maneja bien las subconsultas. Se han realizado algunos trabajos importantes para modernizar el optimizador para 6.0 y las subconsultas funcionan mucho mejor ahora, pero estos cambios no se han introducido en las series 5.0 o 5.1.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top