Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

cách hiệu quả để triển khai phân trang

Cố gắng cung cấp cho bạn câu trả lời ngắn gọn cho sự nghi ngờ của bạn, nếu bạn thực thi skip(n).take(m) trên linq (với SQL 2005/2008 làm máy chủ cơ sở dữ liệu) truy vấn của bạn sẽ sử dụng Select ROW_NUMBER() Over ... câu lệnh, với bằng cách nào đó là phân trang trực tiếp trong công cụ SQL.

Cho bạn một ví dụ, tôi có một bảng db được gọi là mtcity và tôi đã viết truy vấn sau (hoạt động tốt với linq đối với các thực thể):

using (DataClasses1DataContext c = new DataClasses1DataContext())
{
    var query = (from MtCity2 c1 in c.MtCity2s
                select c1).Skip(3).Take(3);
    //Doing something with the query.
}

Truy vấn kết quả sẽ là:

SELECT [t1].[CodCity], 
    [t1].[CodCountry], 
    [t1].[CodRegion], 
    [t1].[Name],  
    [t1].[Code]
FROM (
    SELECT ROW_NUMBER() OVER (
        ORDER BY [t0].[CodCity], 
        [t0].[CodCountry], 
        [t0].[CodRegion], 
        [t0].[Name],
        [t0].[Code]) AS [ROW_NUMBER], 
        [t0].[CodCity], 
        [t0].[CodCountry], 
        [t0].[CodRegion], 
        [t0].[Name],
        [t0].[Code]
    FROM [dbo].[MtCity] AS [t0]
    ) AS [t1]
WHERE [t1].[ROW_NUMBER] BETWEEN @p0 + 1 AND @p0 + @p1
ORDER BY [t1].[ROW_NUMBER]

Đó là quyền truy cập dữ liệu dạng cửa sổ (khá thú vị, btw cuz sẽ trả về dữ liệu kể từ đầu và sẽ truy cập bảng miễn là đáp ứng các điều kiện). Điều này sẽ rất giống với:

With CityEntities As 
(
    Select ROW_NUMBER() Over (Order By CodCity) As Row,
        CodCity //here is only accessed by the Index as CodCity is the primary
    From dbo.mtcity
)
Select [t0].[CodCity], 
        [t0].[CodCountry], 
        [t0].[CodRegion], 
        [t0].[Name],
        [t0].[Code]
From CityEntities c
Inner Join dbo.MtCity t0 on c.CodCity = t0.CodCity
Where c.Row Between @p0 + 1 AND @p0 + @p1
Order By c.Row Asc

Ngoại trừ điều đó, truy vấn thứ hai này sẽ được thực thi nhanh hơn kết quả linq vì nó sẽ chỉ sử dụng chỉ mục để tạo cửa sổ truy cập dữ liệu; điều này có nghĩa là, nếu bạn cần một số bộ lọc, bộ lọc phải (hoặc phải có) trong danh sách Đối tượng (nơi hàng được tạo) và một số chỉ mục cũng nên được tạo để duy trì hiệu suất tốt.

Bây giờ, còn gì tốt hơn?

Nếu bạn có quy trình làm việc khá chắc chắn trong logic của mình, thì việc triển khai theo cách SQL thích hợp sẽ rất phức tạp. Trong trường hợp đó, LINQ sẽ là giải pháp.

Nếu bạn có thể hạ thấp phần logic đó trực tiếp xuống SQL (trong một quy trình được lưu trữ), thì sẽ tốt hơn nữa vì bạn có thể triển khai truy vấn thứ hai mà tôi đã chỉ cho bạn (sử dụng các chỉ mục) và cho phép SQL tạo và lưu trữ Kế hoạch thực thi của truy vấn (cải thiện hiệu suất).



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. chuyển đổi kiểu dữ liệu varchar thành kiểu dữ liệu datetime dẫn đến giá trị nằm ngoài phạm vi

  2. Lỗi SQL Server 213:Tên cột hoặc số lượng giá trị được cung cấp không khớp với định nghĩa bảng.

  3. Làm thế nào để ánh xạ động các cột đầu vào và đầu ra trong SSIS?

  4. SQL:Mệnh đề IF trong mệnh đề WHERE

  5. Tìm hàng cuối cùng trong nhóm theo truy vấn-SQL Server