ฉันมีโต๊ะแบบนี้:
CREATE TABLE Updates
(
UpdateId INT NOT NULL IDENTITY(1,1) PRIMARY KEY,
ObjectId INT NOT NULL
)
การติดตามการอัปเดตพื้นฐานไปยังวัตถุที่มี ID เพิ่มขึ้น
ผู้ใช้บริการของตารางนี้จะเลือกรหัสวัตถุที่แตกต่างกัน 100 รายการเรียงลำดับตาม UpdateId
UpdateId
และเริ่มจากที่เฉพาะเจาะจง โดยพื้นฐานแล้วการติดตามจุดที่มันค้างไว้แล้วทำการสอบถามเพื่อรับการปรับปรุงใด ๆ
ฉันพบสิ่งนี้เป็นปัญหาการปรับให้เหมาะสมที่น่าสนใจเพราะฉันสามารถสร้างแผนคิวรีที่เหมาะสมที่สุดโดยการเขียนคิวรีที่เกิดขึ้นกับสิ่งที่ฉันต้องการเนื่องจากดัชนี แต่ไม่รับประกันสิ่งที่ฉันต้องการ:
SELECT DISTINCT TOP 100 ObjectId
FROM Updates
WHERE UpdateId > @fromUpdateId
ที่ไหน @fromUpdateId
พารามิเตอร์กระบวนงานที่เก็บไว้
ด้วยแผนของ:
SELECT <- TOP <- Hash match (flow distinct, 100 rows touched) <- Index seek
เนื่องจากการค้นหาUpdateId
ดัชนีที่กำลังใช้งานผลลัพธ์ก็ดีอยู่แล้วและเรียงลำดับจาก ID การอัปเดตต่ำสุดถึงสูงสุดอย่างที่ฉันต้องการ และนี่สร้างกระแสที่แตกต่างแผนการซึ่งเป็นสิ่งที่ฉันต้องการ แต่การจัดลำดับไม่ชัดเจนว่ารับประกันพฤติกรรมดังนั้นฉันไม่ต้องการใช้
เคล็ดลับนี้ยังส่งผลในแผนคิวรีแบบเดียวกัน (ด้วย TOP ที่ซ้ำซ้อน):
WITH ids AS
(
SELECT ObjectId
FROM Updates
WHERE UpdateId > @fromUpdateId
ORDER BY UpdateId OFFSET 0 ROWS
)
SELECT DISTINCT TOP 100 ObjectId FROM ids
แม้ว่าฉันไม่แน่ใจ (และไม่สงสัย) หากรับประกันการสั่งซื้ออย่างแท้จริง
หนึ่งแบบสอบถามที่ฉันหวังว่า SQL Server จะฉลาดพอที่จะทำให้มันง่ายขึ้น แต่มันก็จบลงด้วยการสร้างแผนการสืบค้นที่แย่มาก:
SELECT TOP 100 ObjectId
FROM Updates
WHERE UpdateId > @fromUpdateId
GROUP BY ObjectId
ORDER BY MIN(UpdateId)
ด้วยแผนของ:
SELECT <- Top N Sort <- Hash Match aggregate (50,000+ rows touched) <- Index Seek
ฉันกำลังพยายามหาวิธีในการสร้างแผนที่ดีที่สุดด้วยการค้นหาดัชนีUpdateId
และลำดับการไหลที่แตกต่างกันเพื่อลบรายการที่ซ้ำกันObjectId
s ความคิดใด ๆ
ตัวอย่างข้อมูลถ้าคุณต้องการ วัตถุจะมีการอัปเดตมากกว่าหนึ่งครั้งและแทบจะไม่ควรมีมากกว่าหนึ่งรายการภายในชุดของแถวที่ 100 ซึ่งเป็นสาเหตุที่ฉันตามลำดับการไหลที่แตกต่างกันเว้นแต่ว่ามีอะไรที่ดีกว่าที่ฉันไม่รู้ อย่างไรก็ตามไม่มีการรับประกันว่าObjectId
จะไม่มีแถวมากกว่า 100 แถวในตาราง ตารางมีมากกว่า 1,000,000 แถวและคาดว่าจะเติบโตอย่างรวดเร็ว
@fromUpdateId
สมมติว่าผู้ใช้นี้มีวิธีการหาที่เหมาะสมต่อไปอีก ไม่จำเป็นต้องส่งคืนในแบบสอบถามนี้