sql >> Base de Datos >  >> RDS >> Sqlserver

Forma más rápida para esta consulta (Cuál es la mejor estrategia) dado un rango de fechas

Actualización:

Consulte este artículo en mi blog para obtener una estrategia de indexación eficiente para su consulta utilizando columnas calculadas:

La idea principal es que solo calculamos la length redondeada y startDate para sus rangos y luego búsquelos usando condiciones de igualdad (que son buenas para B-Tree índices)

En MySQL y en SQL Server 2008 podrías usar SPATIAL índices (R-Tree ).

Son particularmente buenos para condiciones como "seleccionar todos los registros con un punto dado dentro del rango del registro", que es justo su caso.

Almacenas la start_date y end_date como el principio y el final de un LineString (convirtiéndolos a UNIX marcas de tiempo de otro valor numérico), indexarlos con un SPATIAL indexe y busque todos esos LineString s cuyo cuadro delimitador mínimo (MBR ) contiene el valor de la fecha en cuestión, usando MBRContains .

Vea esta entrada en mi blog sobre cómo hacer esto en MySQL :

y una breve descripción general del rendimiento de SQL Server :

Se puede aplicar la misma solución para buscar una IP dada contra rangos de red almacenados en la base de datos.

Esta tarea, junto con su consulta, es otro ejemplo de tal condición que se usa con frecuencia.

B-Tree simple los índices no son buenos si los rangos pueden superponerse.

Si no pueden (y lo sabes), puedes usar la brillante solución propuesta por @AlexKuznetsov

También tenga en cuenta que el rendimiento de esta consulta depende totalmente de su distribución de datos.

Si tiene muchos registros en B y pocos registros en A , podría crear un índice en B.dates y dejar que el TS/CIS en A ir.

Esta consulta siempre leerá todas las filas de A y usará Index Seek en B.dates en un bucle anidado.

Si sus datos se distribuyen al revés, i. mi. tienes muchas filas en A pero pocos en B , y los rangos son generalmente cortos, entonces podría rediseñar un poco sus tablas:

A

start_date interval_length

, cree un índice compuesto en A (interval_length, start_date)

y usa esta consulta:

SELECT  *
FROM    (
        SELECT  DISTINCT interval_length
        FROM    a
        ) ai
CROSS JOIN
        b
JOIN    a
ON      a.interval_length = ai.interval_length
        AND a.start_date BETWEEN b.date - ai.interval_length AND b.date