Використовуючи підзапит для пошуку загальної кількості всіх попередніх записів із відповідним полем, продуктивність на столі з жахливими записами на 50 тис. Без підзапиту запит виконується за кілька мілісекунд. З підзапитом час виконання - вище хвилини.
Для цього запиту результат повинен:
- Включіть лише ті записи в заданий діапазон дат.
- Включіть кількість усіх попередніх записів, не включаючи поточний запис, незалежно від діапазону дат.
Основна схема таблиці
Activity
======================
Id int Identifier
Address varchar(25)
ActionDate datetime2
Process varchar(50)
-- 7 other columns
Приклад даних
Id Address ActionDate (Time part excluded for simplicity)
===========================
99 000 2017-05-30
98 111 2017-05-30
97 000 2017-05-29
96 000 2017-05-28
95 111 2017-05-19
94 222 2017-05-30
очікувані результати
Для діапазону дат 2017-05-29
до2017-05-30
Id Address ActionDate PriorCount
=========================================
99 000 2017-05-30 2 (3 total, 2 prior to ActionDate)
98 111 2017-05-30 1 (2 total, 1 prior to ActionDate)
94 222 2017-05-30 0 (1 total, 0 prior to ActionDate)
97 000 2017-05-29 1 (3 total, 1 prior to ActionDate)
Записи 96 і 95 виключаються з результату, але включаються в PriorCount
підзапит
Поточний запит
select
*.a
, ( select count(*)
from Activity
where
Activity.Address = a.Address
and Activity.ActionDate < a.ActionDate
) as PriorCount
from Activity a
where a.ActionDate between '2017-05-29' and '2017-05-30'
order by a.ActionDate desc
Поточний індекс
CREATE NONCLUSTERED INDEX [IDX_my_nme] ON [dbo].[Activity]
(
[ActionDate] ASC
)
INCLUDE ([Address]) WITH (
PAD_INDEX = OFF,
STATISTICS_NORECOMPUTE = OFF,
SORT_IN_TEMPDB = OFF,
DROP_EXISTING = OFF,
ONLINE = OFF,
ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON
)
Питання
- Які стратегії можна використати для підвищення ефективності цього запиту?
Редагувати 1
У відповідь на питання, що я можу змінити в БД: я можу змінювати індекси, тільки не структуру таблиці.
Редагувати 2
Зараз я додав базовий індекс у Address
стовпчик, але це, схоже, не покращило. В даний час я знаходжу набагато кращі показники зі створенням темп-таблиці та вставкою значень без, PriorCount
а потім оновленням кожного рядка з їх конкретними підрахунками.
Редагувати 3
Проблема, яку знайшов золотник індексу Джо Оббіш (прийнята відповідь). Після того, як я додав новий nonclustered index [xyz] on [Activity] (Address) include (ActionDate)
, час запитів зменшився від хвилини до менше секунди, не використовуючи тимчасову таблицю (див. Редагування 2).
nonclustered index [xyz] on [Activity] (Address) include (ActionDate)
, час запитів зменшився від хвилини до менше секунди. +10, якби міг. Спасибі!