php
  • mysql
  • performance
  • 2012-03-29 9 views 29 likes 
    29

    Esta es una pregunta bastante simple y supongo que la respuesta es "No importa", pero tengo que preguntar de todos modos ...Rendimiento de MySQL - Cláusula "IN" vs Iguales (=) para un valor único

    que tienen una instrucción SQL genérica construida en PHP:

    $sql = 'SELECT * FROM `users` WHERE `id` IN(' . implode(', ', $object_ids) . ')'; 
    

    Suponiendo que las comprobaciones de validez anteriores ($object_ids es una matriz con al menos 1 elemento y todos los valores numéricos), debería hacer lo siguiente en su lugar?

    if(count($object_ids) == 1) { 
        $sql = 'SELECT * FROM `users` WHERE `id` = ' . array_shift($object_ids); 
    } else { 
        $sql = 'SELECT * FROM `users` WHERE `id` IN(' . implode(', ', $object_ids) . ')'; 
    } 
    

    O es la sobrecarga de comprobación count($object_ids) no vale la pena lo que se guarda en la instrucción SQL real (o ninguna en absoluto)?

    +0

    Has respondido a tu pregunta :) no importa. También es más fácil usar 'implode' sin verificar el tamaño de la matriz. –

    +1

    @ N.B. ¿Alguna vez alguien le dijo que su nombre es perfecto para comentarios: P – mellamokb

    +0

    @mellamokb - ahora alguien lo hizo :) –

    Respuesta

    14

    Ninguno de ellos realmente importa en el gran alcance de las cosas. La latencia de la red en la comunicación con la base de datos superará con creces la sobrecarga de count($object_ids) o la sobrecarga de = frente a IN. Yo llamaría a esto un caso de optimización prematura.

    Debe realizar un perfil y probar la carga de su aplicación para conocer dónde están los cuellos de botella reales.

    +0

    Gracias, solo necesitaba un poco de tranquilidad – JudRoman

    +0

    ¡Esto realmente no respondió la pregunta! –

    23

    No hay diferencia entre los enunciados de MySQL, y el optimizador de MySQL transformará el IN en = cuando IN es solo un elemento. No te molestes

    +4

    ¿Podría traer alguna información oficial de MySQL para confirmar su afirmación? ¿Estás completamente seguro de que el optimizador de MySQL lo transformará como lo explicaste? – Delmo

    +2

    No es cierto, ejecuto una consulta con declaración de explicación y capturas de pantalla publicadas como una respuesta – mes

    3

    Imagino que internamente MySQL tratará la consulta IN (6) exactamente como una consulta = 6 lo que no hay necesidad de molestar (esto se llama la optimización prematura por cierto)

    7

    Ejecutar las dos consultas con un comunicado de explicar. Esto le mostrará lo que MySQL está haciendo. Usted se centra en la optimización de MySQL debe estar en lo que está haciendo MySQL con la consulta internamente. Tratar de optimizar qué consulta se ejecuta es un poco prematuro.

    Ambas consultas pueden tener un rendimiento terrible si no hay un índice, por ejemplo. La declaración EXPLAIN de MySQL es oro aquí. Entonces, cuando llegue a una consulta que se está ejecutando lentamente, la instrucción EXPLAIN le mostrará por qué.

    0

    corro consulta con la declaración explicar y aquí están los resultados enter image description here

    Es obvio que "es igual a" operador es mejor, que escanea 13 fila, y "IN" escanea todas las filas

    +1

    Su consulta tiene una subconsulta, por lo que no es necesariamente una indicación de la optimización de 'IN' con un elemento – Vadim

    35

    La mayoría de las otras respuestas no proporcionan nada concluyente, solo especulación. Entonces, basado en el good advice from @Namphibian's answer, ejecuté un EXPLAIN en algunas consultas similares a las del OP.

    Los resultados están a continuación:


    EXPLAIN para una consulta con = 1:

    Explain for a query with <code>= 1</code>


    EXPLAIN para una consulta con IN(1):

    Explain for a query with <code>IN(1)</code>


    EXPLAIN para una consulta con IN(1,2,3):

    Explain for a query with <code>IN(1,2,3)</code>


    Como se puede ver, MySQL optimizar IN(1) a ser el mismo que = 1 en este tipo de consulta. @mes's answer parece indicar que este no siempre es el caso con consultas más complejas, sin embargo.

    Por lo tanto, para aquellos que eran demasiado perezosos para ejecutar el EXPLAIN, ahora lo saben. Y sí, puede ejecutar el EXPLAIN en su propia consulta para asegurarse de que se maneje de esta manera. :-)

    Cuestiones relacionadas