Pregunta

Estoy construyendo unos informes personalizados contra una base de datos de SQL Server 2005. La base de datos pertenece a una tercera aplicación de gestión de fiesta corremos. Los datos que estoy tirando no es uno de los propósitos principales del sitio, por lo que los datos son en gran parte no indexado a excepción de la columna de marca de tiempo. Por ahora, sólo hay una tabla involucrada - una mesa de unos 700 millones de filas. Así que cuando ejecuta una consulta contra ella que debe devolver sólo 50 filas, se ha de reconocer todos los 700mil.

Estoy buscando a acelerar este proceso, pero no quieren índice de cada columna que estoy añadiendo a la cláusula WHERE - No sé que añadir que muchos índices terminarán la mejora de la velocidad mucho ( o estoy equivocado?). Así que estoy curioso lo que sería la mejor práctica si podría no añadir nuevos índices de la tabla!

El procedimiento almacenado no parece ser la mejor opción. Una vista indizada puede ser la mejor idea? Pensamientos?

Este es el esquema de la tabla:

DeviceGuid (PK, uniqueidentifier, not null)
DeviceID (int, not null)
WindowsEventID (PK, int, not null) (indexed)
EventLog (varchar(64), not null)
EventSource (varchar(64), not null)
EventID (int, not null)
Severity (int, not null)
Description (nvarchar(max), not null)
TimeOfEvent (PK, datetime, not null) (indexed)
OccurrenceNbr (int, not null)

Aquí hay una consulta de ejemplo:

SELECT COUNT(*) AS NumOcc, EventID, EventLog, EventSource, Severity, TimeOfEvent, Description
FROM WindowsEvent
WHERE DeviceID='34818'
    AND Severity=1
    AND TimeOfEvent >= DATEADD(hh, DATEDIFF(hh, GETDATE(), GETUTCDATE()), '2010/10/27 12:00:00 AM')
    AND TimeOfEvent <= DATEADD(hh, DATEDIFF(hh, GETDATE(), GETUTCDATE()), '2010/11/3 12:00:00 AM')
    AND EventID<>34113
    AND EventID<>34114
    AND EventID<>34112
    AND EventID<>57755
    AND EventSource<>'AutoImportSvc.exe'
    AND EventLog='Application'
GROUP BY EventID, EventLog, EventSource, Severity, Description
ORDER BY NumOcc DESC

Tal vez la consulta chupa ... regresa 53 filas en 4,5 minutos.

¿Fue útil?

Solución 3

La solución final fue aquí para ejecutar una consulta en los campos indexados, filtrarlos dentro de la aplicación que se ejecuta la consulta. Dos campos terminaron contiene suficiente información similar que pude consulta en un índice y obtener una aproximación muy cercana de los datos que quería. I devuelto de regreso a través y eliminado todo entidades no coincidentes de la lista de resultados. Tomó mucho menos tiempo!

Otros consejos

Si la consulta no está utilizando ningún índice que va a ser muy malo. No es necesario un índice en cada columna, pero usted querrá uno en la columna de la derecha. Teniendo en cuenta que TimeOfEvent ya está indexada, puede que no sea una gran opción para sus necesidades.

La columna de la derecha va a depender de la distribución de los datos. El mejor índice será probablemente el índice que proporciona selectividad más alta (es decir, cuando se conoce un valor clave para el índice devuelve el menor número de filas). Si conoce la columna que proporciona la mejor selectividad, puede probar el índice sobre el mismo.

Para ayudar a determinar el mejor índice, puede utilizar el plan de ejecución estimado en SSMS. Esto le ayudará a ver qué índice será utilizado. Después de la adición de un índice, puede ejecutar la consulta y evaluar los resultados con el plan de ejecución. Y, por supuesto, observando el tiempo transcurrido ayudará también.

probar este método utilizando el truco de doble row_number:

SELECT  RN_Desc as NumOcc, *
FROM    (
        SELECT  row_number() Over(partition by EventId order by EventLog, EventSource, Severity, Description) as RN_Asc,
                row_number() Over(partition by EventId order by EventLog desc, EventSource desc, Severity desc, Description desc) as RN_Desc,
                *
        FROM    WindowsEvent 
        WHERE   DeviceID='34818' 
                AND Severity=1 
                AND TimeOfEvent >= DATEADD(hh, DATEDIFF(hh, GETDATE(), GETUTCDATE()), '2010/10/27 12:00:00 AM') 
                AND TimeOfEvent <= DATEADD(hh, DATEDIFF(hh, GETDATE(), GETUTCDATE()), '2010/11/3 12:00:00 AM') 
                AND EventID<>34113 
                AND EventID<>34114 
                AND EventID<>34112 
                AND EventID<>57755 
                AND EventSource<>'AutoImportSvc.exe' 
                AND EventLog='Application' 
        ) t
WHERE   RN_Asc = 1 
ORDER BY NumOcc DESC 

con este motor no necesita hacer ningún agregaciones de una sola pasada a través de la mesa. si no lo hace el trabajo de juego intento con el fin de partición y por partes de la rownumber para obtener agrupaciones correctas.

Esto es bastante ingenuo, pero me gustaría probar el valor indexado como la primera prueba en el

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