ฉันจะเขียน. Skip (1000) ของ LINQ ได้อย่างไร (100) ใน SQL บริสุทธิ์


93

SQL เทียบเท่ากับ.Skip()วิธีการใน LINQ คืออะไร?

ตัวอย่างเช่นฉันต้องการเลือกแถว 1,000-1100 จากตารางฐานข้อมูลเฉพาะ

เป็นไปได้ด้วย SQL เพียงอย่างเดียวหรือไม่? หรือฉันต้องเลือกทั้งตารางจากนั้นค้นหาแถวในหน่วยความจำ ฉันอยากจะหลีกเลี่ยงสิ่งนี้ถ้าเป็นไปได้เนื่องจากโต๊ะอาจมีขนาดค่อนข้างใหญ่

คำตอบ:


78

ใน SQL Server 2005 ขึ้นไปคุณสามารถใช้ฟังก์ชันROW_NUMBER เช่น.

USE AdventureWorks;
GO
WITH OrderedOrders AS
(
    SELECT SalesOrderID, OrderDate,
    ROW_NUMBER() OVER (ORDER BY OrderDate) AS 'RowNumber'
    FROM Sales.SalesOrderHeader 
) 
SELECT * 
FROM OrderedOrders 
WHERE RowNumber BETWEEN 51 AND 60; --BETWEEN is inclusive

ดูลิงก์ในคำตอบของฉันสำหรับรายละเอียดเพิ่มเติมเล็กน้อย stackoverflow.com/questions/1744802/…
Mike Atlas

ระหว่าง 51 และ 60 - รวมอยู่ด้วย
Drew Miller

1
แต่นี่จะเลือกทั้งหมดก่อนแล้วจากการเลือกนั้นใช้เวลาเพียง 10 ใช่ไหม? หรือแบบสอบถาม / มุมมองแรกจะมีเพียง 10 ครั้งแล้ว?
ธ เดช

139

SQL Server 2012 ขึ้นไปได้เพิ่มไวยากรณ์นี้:

SELECT *
FROM Sales.SalesOrderHeader 
ORDER BY OrderDate
OFFSET (@Skip) ROWS FETCH NEXT (@Take) ROWS ONLY

11
โปรดทราบว่าคุณต้องใช้ ORDER BY ___ เพื่อใช้คำสั่ง OFFSET .... ไม่ใช่ว่าคุณควรลองใช้การแบ่งหน้าโดยไม่มีคำสั่ง
James Haug

นอกจากนี้โปรดทราบว่าไวยากรณ์ 'ใหม่' แปลก ๆ มีเส้นตรงจุดโทษประสิทธิภาพด้วย @skip! วิธี row_number ไม่มีสิ่งนี้ (ทดสอบตามลำดับที่จัดทำดัชนีเท่านั้น) สำหรับ lo @Skip น้อยกว่า 20 ไวยากรณ์ใหม่จะเร็วกว่าวิธี row_number
Eske Rahn

22

LINQ เป็น SQL ทำได้โดยใช้ฟังก์ชันการสร้างหน้าต่าง ROW_NUMBER:

  SELECT a,b,c FROM 
   (SELECT a,b,c, ROW_NUMBER() OVER (ORDER BY ...) as row_number
    FROM Table) t0
   WHERE to.row_number BETWEEN 1000 and 1100;

วิธีนี้ใช้ได้ผล แต่ความจำเป็นในการสร้าง row_number จาก ORDER BY อาจส่งผลให้การสืบค้นของคุณถูกจัดเรียงบนฝั่งเซิร์ฟเวอร์และทำให้เกิดปัญหาด้านประสิทธิภาพ แม้ว่าดัชนีจะสามารถตอบสนองความต้องการ ORDER BY แต่แบบสอบถามยังคงต้องนับ 1,000 แถวก่อนที่จะเริ่มส่งคืนผลลัพธ์ บ่อยครั้งที่นักพัฒนาลืมสิ่งนี้และเพียงแค่โยนการควบคุมการแบ่งหน้าบนตาราง 5 ล้านแถวและสงสัยว่าทำไมหน้าแรกจึงกลับมาเร็วกว่าหน้าสุดท้ายมาก ...

การใช้ ROW_NUMBER () อาจเป็นความสมดุลที่ดีที่สุดระหว่างความสะดวกในการใช้งานและประสิทธิภาพที่ดีหากคุณต้องแน่ใจว่าคุณหลีกเลี่ยงการเรียงลำดับ (สามารถกำหนดเงื่อนไข ORDER BY โดยดัชนีได้)


1
ขอบคุณสำหรับข้อมูลประสิทธิภาพเพิ่มเติมจะต้องระมัดระวังและทดสอบ
เรย์

ผ่านการทดสอบและสำหรับตารางครึ่งล้านแถวของฉันหน้าสุดท้ายนั้นช้ากว่าหน้าแรกประมาณ 7 เท่า ไม่เหมาะ แต่เป็นที่ยอมรับสำหรับฉัน
Ray

6

ลองอันนี้:

select * from [Table-Name] order by [Column-Name] 
offset [Skip-Count] rows
FETCH NEXT [Take-Count] rows only

ตัวอย่าง:

select * from Personals order by Id
offset 10 rows            --------->Skip 10
FETCH NEXT 15 rows only   --------->Take 15

4

ทำเช่นนี้:

Run. Skip (1000). Take (100) บน LINQ ไปยัง SQL datacontext และดูที่เอาต์พุต SQL มันจะสร้างคำสั่ง SQL สำหรับคุณที่ทำในสิ่งที่คุณกำลังอธิบาย

มันจะไม่สวยหรู แต่ก็ทำให้งานลุล่วง


2
ไม่ใช่สิ่งที่ถูกถาม
RayLoveless

2

ไม่ได้ แต่คุณสามารถจำลองประโยค LIMIT ของ MySQL (ลิงก์ Stack Overflow) เพื่อให้ได้ผลลัพธ์เดียวกัน


1
คำตอบที่ได้รับการยอมรับชี้ไปที่ลิงก์ CodeProject ที่น่าสนใจ"Paging of Large Resultsets ใน ASP.NET" (เน้น SQL มากกว่าที่ชื่อแนะนำ)
ruffin
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.