Pregunta

¿Son las siguientes consultas eficaces en MySQL:

SELECT * FROM table WHERE field & number = number; 
# to find values with superset of number's bits

SELECT * FROM table WHERE field | number = number; 
# to find values with subset of number's bits

... si se ha creado un índice para el campo?

Si no, ¿hay una manera de hacer que se ejecute más rápido?

¿Fue útil?

Solución

Actualización:

Vea esta entrada en mi blog para los detalles de rendimiento:


SELECT * FROM table WHERE field & number = number

SELECT * FROM table WHERE field | number = number

Este índice puede ser eficaz en dos formas:

  1. Para evitar recorridos de tablas primeros (ya que el valor de comparar está contenida en el propio índice)
    • Para limitar el rango de valores examinados.

Ninguna de estas condiciones en las consultas anterior es sargable , este es el índice no será utilizado para la exploración de distancia (con las condiciones, ya que son ahora).

Sin embargo, el punto 1 todavía lleva a cabo, y el índice puede ser útil.

Si su tabla contiene, por ejemplo, 100 bytes por fila en la media, y los registros 1,000,000, entonces el recorrido de tabla tendrá que escanear 100 Mb de datos.

Si usted tiene un índice (con una llave 4 bytes, puntero de fila 6 bytes y algo de sobrecarga interna), la consulta tendrá que analizar sólo 10 Mb de los datos, además de datos adicionales de la tabla si el filtro tiene éxito.

  • El recorrido de tabla es más eficiente si su condición no es selectivo (que tiene alta probablility para que coincida con la condición).
  • El recorrido de índice es más eficiente si su condición es selectiva (que tiene baja probablility para que coincida con la condición).

Tanto estas consultas requerirán el escaneo de todo el índice.

Pero volviendo a escribir la consulta AND se puede beneficiar de la que van en el índice también.

Esta condición:

field & number = number

sólo puede coincidir con los campos si los bits más altos del conjunto number se establecen en el field también.

Y sólo debe proporcionar esta condición adicional para la consulta:

SELECT  *
FROM    table
WHERE   field & number = number
        AND field >= 0xFFFFFFFF & ~((2 << FLOOR(LOG(2, 0xFFFFFFFF & ~number))) - 1)

Esto utilizará el rango para el filtrado grueso y la condición para el filtrado fino.

Los más bits para number son unset al final, mejor.

Otros consejos

Dudo que el optimizador se daría cuenta de que uno ...

Tal vez se puede llamar explique en estas consultas y confirmar mi suposición pesimista. (Recordando por supuesto que gran parte de las decisiones del plan de consulta se basa en la instancia específica de una base de datos dada, es decir, cantidades variables de datos y / mineral meramente de datos con un perfil estadístico diferente puede producir planes distintos).

Suponiendo que la tabla tiene una cantidad significativa de filas, y que los criterios "bitwised" siguen siendo lo suficientemente selectiva) una posible optimización se consigue al evitar una operación a nivel de bits en cada hilera, reescribiendo la consulta con un constructo de IN (o con un JOIN)

Algo así (conceptual, es decir, no probado)

CREATE TEMPORARY TABLE tblFieldValues
  (Field INT);

INSERT INTO tblFieldValues
   SELECT DISTINCT Field
   FROM table;

-- SELECT * FROM table WHERE field | number = number; 
-- now becomes
SELECT * 
FROM table t
WHERE field IN 
    (SELECT Field 
     FROM tblFieldValues 
     WHERE field | number = number); 

Los beneficios de un enfoque como este deben ser evaluados con diferentes casos de uso (todos los cuales con un considerable número de filas en la tabla, ya que de lo contrario el directo "donde el campo | número = número" enfoque es lo suficientemente eficiente), pero sospecho que esto podría ser significativamente más rápido. Más ganancias pueden lograrse si los "tblFieldValues" no tiene que ser recreada cada vez. creación eficiente de esta tabla, por supuesto, implica un índice en el campo en la tabla original.

He intentado esto mismo, y las operaciones bit a bit no son suficientes para prevenir Mysql del uso de un índice en la columna de "campo". Es probable, sin embargo, que un análisis completo del índice está teniendo lugar.

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