Eşleşen bir alana sahip önceki tüm kayıtların toplam sayısını bulmak için bir alt sorgu kullanırken, performans 50 bin kadar az kayıt içeren bir tabloda korkunçtur. Alt sorgu olmadan, sorgu birkaç milisaniye içinde yürütülür. Alt sorgu ile yürütme süresi bir dakikadır.
Bu sorgu için sonuç:
- Yalnızca belirli bir tarih aralığındaki kayıtları dahil et.
- Tarih aralığından bağımsız olarak, geçerli kayıt dahil değil önceki tüm kayıtların sayısını ekleyin.
Temel Tablo Şeması
Activity
======================
Id int Identifier
Address varchar(25)
ActionDate datetime2
Process varchar(50)
-- 7 other columns
Örnek Veriler
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
Beklenen sonuçlar
Tarih aralığı 2017-05-29
için2017-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 ve 95 kayıtları sonuçtan hariç tutulur, ancak PriorCount
alt sorguya dahil edilir
Geçerli Sorgu
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
Mevcut Dizin
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
)
Soru
- Bu sorgunun performansını artırmak için hangi stratejiler kullanılabilir?
Edit 1
DB üzerinde ne değiştirebilirim sorusuna cevap olarak: Ben dizinleri, sadece tablo yapısını değiştirebilir.
Edit 2
Şimdi Address
sütuna temel bir dizin ekledim , ancak bu pek gelişmedi. Şu anda bir geçici tablo oluşturma ve değerleri olmadan ekleme PriorCount
ve daha sonra her satır belirli sayıları ile güncelleme ile çok daha iyi performans buluyorum .
Edit 3
Endeks Biriktirme Joe Obbish (kabul edilen cevap) sorun bulundu. Yeni bir kez eklediğimde, nonclustered index [xyz] on [Activity] (Address) include (ActionDate)
geçici tablo kullanmadan sorgu süreleri bir dakikadan bir saniyeden bir saniyeye indirildi (bakınız düzenleme 2).
nonclustered index [xyz] on [Activity] (Address) include (ActionDate)
, sorgu süreleri bir dakika yukarı bir saniyeden daha az düştü. Yapabilirsem +10. Teşekkürler!