Saat menggunakan subquery untuk menemukan jumlah total semua catatan sebelumnya dengan bidang yang cocok, kinerjanya mengerikan di atas meja dengan hanya 50k catatan. Tanpa subquery, query dieksekusi dalam beberapa milidetik. Dengan subquery, waktu eksekusi lebih dari satu menit.
Untuk kueri ini, hasilnya harus:
- Hanya sertakan catatan-catatan itu dalam rentang tanggal tertentu.
- Sertakan hitungan semua catatan sebelumnya, tidak termasuk catatan saat ini, terlepas dari rentang tanggal.
Skema Tabel Dasar
Activity
======================
Id int Identifier
Address varchar(25)
ActionDate datetime2
Process varchar(50)
-- 7 other columns
Contoh Data
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
hasil yang diharapkan
Untuk rentang tanggal 2017-05-29
hingga2017-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)
Catatan 96 dan 95 dikecualikan dari hasil, tetapi dimasukkan dalam PriorCount
subquery
Permintaan Saat Ini
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
Indeks saat ini
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
)
Pertanyaan
- Strategi apa yang dapat digunakan untuk meningkatkan kinerja permintaan ini?
Sunting 1
Sebagai jawaban untuk pertanyaan tentang apa yang dapat saya modifikasi pada DB: Saya dapat mengubah indeks, hanya saja bukan struktur tabelnya.
Sunting 2
Saya sekarang telah menambahkan indeks dasar pada Address
kolom, tetapi tampaknya tidak banyak membaik. Saat ini saya menemukan kinerja yang jauh lebih baik dengan membuat tabel temp dan memasukkan nilai tanpa PriorCount
dan kemudian memperbarui setiap baris dengan jumlah spesifik mereka.
Sunting 3
Indeks Spool Joe Obbish (jawaban yang diterima) ditemukan adalah masalahnya. Setelah saya menambahkan yang baru nonclustered index [xyz] on [Activity] (Address) include (ActionDate)
, waktu kueri turun dari atas satu menit menjadi kurang dari satu detik tanpa menggunakan tabel temp (lihat edit 2).
nonclustered index [xyz] on [Activity] (Address) include (ActionDate)
, waktu kueri turun dari atas satu menit menjadi kurang dari satu detik. +10 jika aku bisa. Terima kasih!