สมมติว่ามีการจัดทำดัชนีคอลัมน์ต่อไปนี้ควรมีประสิทธิภาพพอสมควร
ด้วยการค้นหาสองแถว 10 แถวจากนั้นเรียงลำดับ (ถึง) 20 คืน
WITH CTE
AS ((SELECT TOP 10 *
FROM YourTable
WHERE YourCol > 32
ORDER BY YourCol ASC)
UNION ALL
(SELECT TOP 10 *
FROM YourTable
WHERE YourCol <= 32
ORDER BY YourCol DESC))
SELECT TOP 10 *
FROM CTE
ORDER BY ABS(YourCol - 32) ASC
(เช่นอาจเป็นสิ่งที่ต้องการด้านล่าง)
หรือความเป็นไปได้อื่น (ที่ช่วยลดจำนวนแถวที่เรียงลำดับไว้สูงสุด 10)
WITH A
AS (SELECT TOP 10 *,
YourCol - 32 AS Diff
FROM YourTable
WHERE YourCol > 32
ORDER BY Diff ASC, YourCol ASC),
B
AS (SELECT TOP 10 *,
32 - YourCol AS Diff
FROM YourTable
WHERE YourCol <= 32
ORDER BY YourCol DESC),
AB
AS (SELECT *
FROM A
UNION ALL
SELECT *
FROM B)
SELECT TOP 10 *
FROM AB
ORDER BY Diff ASC
หมายเหตุ: แผนการดำเนินการข้างต้นมีไว้สำหรับคำจำกัดความของตารางอย่างง่าย
CREATE TABLE [dbo].[YourTable](
[YourCol] [int] NOT NULL CONSTRAINT [SomeIndex] PRIMARY KEY CLUSTERED
)
ในทางเทคนิคแล้วการเรียงลำดับที่สาขาด้านล่างไม่จำเป็นเช่นกันเนื่องจาก Diff เรียงลำดับเช่นกันและเป็นไปได้ที่จะรวมผลลัพธ์ที่ได้รับคำสั่งสองรายการเข้าด้วยกัน แต่ฉันไม่สามารถทำตามแผนนั้นได้
แบบสอบถามมีORDER BY Diff ASC, YourCol ASC
และไม่เพียงORDER BY YourCol ASC
เพราะนั่นคือสิ่งที่สิ้นสุดการทำงานเพื่อกำจัดการเรียงลำดับในสาขาด้านบนของแผน ฉันต้องการเพิ่มคอลัมน์รองใน (แม้ว่าจะไม่เปลี่ยนผลลัพธ์เหมือนYourCol
เดิมสำหรับค่าทั้งหมดที่มี Diff เดียวกัน) ดังนั้นจะต้องผ่านการรวมการผสาน (การต่อข้อมูล) โดยไม่เพิ่มการเรียงลำดับ
ดูเหมือนว่า SQL Server สามารถอนุมานได้ว่าดัชนีบน X ที่ค้นหาตามลำดับจากน้อยไปหามากจะส่งแถวที่สั่งโดย X + Y และไม่จำเป็นต้องมีการเรียงลำดับ แต่ไม่สามารถอนุมานได้ว่าการเดินทางดัชนีตามลำดับจากมากไปน้อยจะส่งแถวในลำดับเดียวกับ YX (หรือแม้แต่เพียงแค่ลบเครื่องหมาย X ลบ) สาขาทั้งสองของแผนใช้ดัชนีเพื่อหลีกเลี่ยงการเรียงลำดับ แต่TOP 10
ในสาขาด้านล่างจะถูกจัดเรียงตามDiff
(แม้ว่าพวกเขาจะมีอยู่แล้วในลำดับนั้น) เพื่อรับพวกเขาตามลำดับที่ต้องการสำหรับการผสาน
สำหรับการสืบค้นอื่น ๆ / คำจำกัดความของตารางมันอาจจะมีเล่ห์เหลี่ยมหรือไม่สามารถรับแผนผสานด้วยการเรียงลำดับของสาขาเดียว - เนื่องจากมันขึ้นอยู่กับการค้นหานิพจน์การสั่งซื้อที่ SQL Server:
- ยอมรับว่าการค้นหาดัชนีจะจัดหาคำสั่งที่ระบุดังนั้นไม่จำเป็นต้องเรียงลำดับก่อนด้านบน
- มีความสุขที่จะใช้ในการดำเนินการผสานจึงไม่ต้องเรียงลำดับหลังจาก
TOP
SELECT TOP 10 * FROM YourTable ORDER BY ABS(YourCol - 32) ;
ง่ายยิ่งขึ้น ไม่มีประสิทธิภาพเช่นกัน