Khi sử dụng truy vấn con để tìm tổng số tất cả các bản ghi trước đó với trường khớp, hiệu suất rất tệ trên một bảng có ít nhất là 50 nghìn bản ghi. Không có truy vấn con, truy vấn sẽ thực hiện trong vài mili giây. Với truy vấn con, thời gian thực hiện lên đến một phút.
Đối với truy vấn này, kết quả phải:
- Chỉ bao gồm những hồ sơ trong một phạm vi ngày nhất định.
- Bao gồm số lượng của tất cả các hồ sơ trước đó, không bao gồm hồ sơ hiện tại, bất kể phạm vi ngày.
Lược đồ bảng cơ bản
Activity
======================
Id int Identifier
Address varchar(25)
ActionDate datetime2
Process varchar(50)
-- 7 other columns
Dữ liệu mẫu
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
Kết quả dự kiến
Đối với phạm vi ngày 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)
Bản ghi 96 và 95 được loại trừ khỏi kết quả, nhưng được bao gồm trong PriorCount
truy vấn con
Truy vấn hiện tại
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
Chỉ số hiện tại
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
)
Câu hỏi
- Những chiến lược nào có thể được sử dụng để cải thiện hiệu suất của truy vấn này?
Chỉnh sửa 1
Trả lời câu hỏi về những gì tôi có thể sửa đổi trên DB: Tôi có thể sửa đổi các chỉ mục, không chỉ là cấu trúc bảng.
Chỉnh sửa 2
Bây giờ tôi đã thêm một chỉ mục cơ bản trên Address
cột, nhưng điều đó dường như không cải thiện nhiều. Tôi hiện đang tìm thấy hiệu suất tốt hơn nhiều với việc tạo bảng tạm thời và chèn các giá trị mà không cần PriorCount
cập nhật từng hàng với số lượng cụ thể của chúng.
Chỉnh sửa 3
Chỉ số Spool Joe Obbish (câu trả lời được chấp nhận) được tìm thấy là vấn đề. Khi tôi đã thêm một cái mới nonclustered index [xyz] on [Activity] (Address) include (ActionDate)
, thời gian truy vấn giảm dần từ một phút xuống dưới một giây mà không sử dụng bảng tạm thời (xem chỉnh sửa 2).
nonclustered index [xyz] on [Activity] (Address) include (ActionDate)
, thời gian truy vấn giảm dần từ một phút xuống dưới một giây. +10 nếu tôi có thể. Cảm ơn!