เมื่อใช้แบบสอบถามย่อยเพื่อค้นหาจำนวนรวมของระเบียนก่อนหน้าทั้งหมดที่มีเขตข้อมูลที่ตรงกันประสิทธิภาพจะแย่มากในตารางที่มีระเบียนน้อยถึง 50k โดยไม่มีแบบสอบถามย่อยแบบสอบถามดำเนินการในไม่กี่มิลลิวินาที ด้วยแบบสอบถามย่อยเวลาดำเนินการขึ้นไปหนึ่งนาที
สำหรับแบบสอบถามนี้ผลลัพธ์จะต้อง:
- รวมเฉพาะบันทึกเหล่านั้นภายในช่วงวันที่ที่กำหนด
- รวมการนับของระเบียนก่อนหน้าทั้งหมดไม่รวมระเบียนปัจจุบันโดยไม่คำนึงถึงช่วงวันที่
โครงสร้างตารางพื้นฐาน
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
ในการตอบคำถามที่ฉันสามารถแก้ไขได้ใน DB: ฉันสามารถแก้ไขดัชนีได้ไม่ใช่โครงสร้างของตาราง
แก้ไข 2
ตอนนี้ฉันได้เพิ่มดัชนีพื้นฐานในAddress
คอลัมน์ แต่ดูเหมือนจะไม่ปรับปรุงมากนัก ขณะนี้ฉันกำลังค้นหาประสิทธิภาพที่ดีขึ้นมากด้วยการสร้างตารางชั่วคราวและแทรกค่าโดยไม่ต้องPriorCount
จากนั้นอัปเดตแต่ละแถวด้วยจำนวนที่เฉพาะเจาะจง
แก้ไข 3
ดัชนี Spool Joe Obbish (คำตอบที่ยอมรับ) พบว่าเป็นปัญหา เมื่อฉันเพิ่มเข้าไปใหม่nonclustered index [xyz] on [Activity] (Address) include (ActionDate)
เวลาค้นหาจะลดลงจากขึ้นไปหนึ่งนาทีถึงน้อยกว่าหนึ่งวินาทีโดยไม่ใช้ตารางชั่วคราว (ดูแก้ไข 2)
nonclustered index [xyz] on [Activity] (Address) include (ActionDate)
เวลาค้นหาจะลดลงจากขึ้นไปหนึ่งนาทีหรือน้อยกว่าหนึ่งวินาที +10 ถ้าทำได้ ขอบคุณ!