2010-11-24 29 views
8

En el trabajo que teníamos una consulta en una tabla que tenía la siguiente estructura:¿Por qué es esta consulta basada gama mucho más rápido

ip_from(number), ip_to(number), country, city, state, isp, latitude, longitude. 

Esta tabla tenía aproximadamente 6,1 millones de filas.

Para conocer los detalles de una determinada dirección IP se utilizó una consulta como la siguiente:

SELECT * 
    FROM Ip2location 
WHERE 
    :ip_num BETWEEN ip_from AND ip_to; 

en Oracle 10 en nuestra base de datos dev esto tomó aproximadamente 17 segundos para devolver una fila, dependiendo de la ip_num pasaron. En nuestro sistema en vivo más robusto, tomó tal vez 5-6 segundos, que aún era demasiado lento para hacer en tiempo real y tuvimos que seleccionar esto a través de un trabajo de fondo.

No ideal, especialmente porque nuestros sistemas en tiempo real realmente necesitaban los detalles de la ip.

El tipo de índice utilizado era un índice de BTREE estándar que abarca tanto ip_from como ip_to. Investigamos muchas cosas para tratar de acelerar esto, como range partitioning. No lo aplicamos al final, ya que requiere Oracle Enterprise. También buscamos aumentar la concurrencia de la tabla, pero eso no tuvo un efecto notable.

De todos modos, al tomar mi café de la mañana me di cuenta de que podría haber una mejora del rendimiento ejecutando la siguiente consulta: (Esto es de memoria, puede haber un par de errores. También seleccionamos campos individuales no todo)

SELECT * 
    FROM ip2location 
WHERE 
    ip_from = (
    SELECT max(ip_from) 
     FROM ip2location 
     WHERE ip_from <= :ip_num 
) 
AND 
    ip_to >= ip_num; 

Esto funciona para nuestro conjunto de datos, ya que no hay rangos que se solapan entre ip_from y ip_to.

Sin embargo, para lo que no estaba preparado es cuánto más rápida es la segunda consulta. El tiempo en nuestra base de datos dev se redujo de 17 segundos a 0.007 segundos.

Esto tiene poco sentido para mí. Esperaría un aumento en el rendimiento, pero no tanto. ¿No deberían las estadísticas de la base de datos darse cuenta de que no hay superposición y se optimizan en consecuencia? ¿También debe haber una manera más rápida y reconocida de seleccionar los rangos?

Mi pregunta es: ¿por qué la segunda consulta es mucho más rápida incluso con una selección secundaria?

+0

has necesitado índices separados en lugar de un ser combinado? –

+0

¿No le explicará el comando explicar por qué? –

+0

@Thomas Padron-McCarthy lo hicimos para la versión anterior de la consulta. Un índice combinado fue más rápido. Tenemos la intención de probar con el único índice en comparación con la nueva consulta. @nate c - No encontré mucho útil en el plan de explicación. Soy un desarrollador no un DBA. ¿Sería útil si en el trabajo incluyese los dos planes de explicación en la pregunta? – Wes

Respuesta

7

el aumento del rendimiento es obvio. Es porque hay un índice en ip_from, por lo que max (ip_from) se puede obtener en tiempo constante porque, como sabes, la indexación ordena los valores. el rango también se calcula fácilmente debido a la búsqueda binaria en btree.

mientras que en la consulta anterior tiene que ver una mesa de exploración en todo los datos para calcular los límites del rango

+0

¿Es cierto a pesar de que hubo un índice combinado? – Wes

+0

Wes: El motor DB no sabe que 'ip_to' nunca es menor que' ip_from'. – Gabe

+0

@Gabe ¿No sabría el motor estadístico esto?Creo que haré un par de preguntas diferentes relacionadas con esta consulta. – Wes

Cuestiones relacionadas