Вопрос

Я создаю несколько пользовательских отчетов против базы данных SQL Server 2005. База данных принадлежит к приложению 3-го вечеринка, которое мы работаем. Данные, которые я потянув, не среди основных целей сайта, поэтому данные в значительной степени неиндексированы, за исключением столбца Timestamp. На данный момент есть только одна таблица - таблица около 700 миллионов строк. Поэтому, когда я бегу к запросу против этого, что должно вернуть только 50 рядов, он должен опросить все 700 мил.

Я ищу это ускорить это, но не хочу индексировать каждый столбец, который я добавляю в пункт откуда - я не знаю, что добавив, что многие индексы в конечном итоге улучшают скорость (или я неправильно?). Так мне интересно, какова была бы лучшая практика, если я не могло Добавьте любые новые индексы в таблицу!

Сохраненная процедура не похоже на лучшее подходящее. Проиндексированное представление может быть лучшей идеей? Мысли?

Вот таблица схемы:

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)

Вот образец запроса:

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

Может быть, запрос отстой ... Он возвращает 53 строк за 4,5 минуты.

Это было полезно?

Решение 3

Конечное решение здесь было запустить запрос на проиндексированные поля, затем фильтруйте их в приложении, выполняющий запрос. Два поля завершились, содержащие достаточно аналогичную информацию, которую я мог бы запросить на один индекс и получить очень тесное приближение данных, которые я хотел. Я обратно обратно и удалил любые не совпадающие объекты из списка результатов. Занял гораздо меньше времени!

Другие советы

Если ваш запрос не использует какие-либо индексы, это будет очень плохо. Вам не нужен индекс на каждом столбце, но вы хотите по одному на правой колонке. Учитывая, что TimeOfEvent уже проиндексирован, это не может быть отличным для ваших нужд.

Правая колонна будет зависеть от распределения ваших данных. Лучший индекс, вероятно, будет индекс, который обеспечивает самую высокую селективность (т. Е. Если вы знаете ключевое значение для индекса, он возвращает наименьшее количество строк). Если вы знаете столбец, которая обеспечивает наилучшую селективность, вы можете попробовать индекс на нем.

Чтобы помочь определить лучший индекс, вы можете использовать план выполнения дисплея в SSMS. Это поможет вам увидеть, какой индекс будет использоваться. После добавления индекса вы можете запустить ваш запрос и оценить результаты с планом выполнения. И, конечно же, наблюдая за истеченным временем.

Попробуйте этот метод, используя двойную rue_number Trick:

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 

С этим двигатель не должен делать какие-либо агрегации всего один проход через таблицу. Если это не сработает, попробуйте играть с заказом и разделы по частям вращенма, чтобы получить правильные группировки.

Это довольно упрошено, но я бы попробую индексированную ценность как первый тест в

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top