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

Hiệu suất SQL:WHERE so với WHERE (ROW_NUMBER)

Như đã chỉ ra khác, các truy vấn trả về các kết quả khác nhau và đang so sánh táo với cam.

Nhưng câu hỏi cơ bản vẫn là: cái nào nhanh hơn:phân trang được điều khiển bằng keyet hay phân trang được điều khiển bởi rownumber?

Phân trang bộ phím

Phân trang theo bộ phím dựa vào việc ghi nhớ các phím trên cùng và dưới cùng của trang được hiển thị cuối cùng và yêu cầu tập hợp các hàng tiếp theo hoặc trước đó, dựa trên bộ phím trên cùng / cuối cùng:

Trang tiếp theo:

select top (<pagesize>) ...
from <table>
where key > @last_key_on_current_page
order by key;

Trang trước:

select top (<pagesize>)
from <table>
where key < @first_key_on_current_page
order by key desc;

Cách tiếp cận này có hai ưu điểm chính so với cách tiếp cận ROW_NUMBER hoặc so với cách tiếp cận LIMIT tương đương của MySQL:

  • đúng :không giống như cách tiếp cận dựa trên số hàng, nó xử lý chính xác các mục nhập mới và mục nhập đã xóa. Hàng cuối cùng của Trang 4 không hiển thị như hàng đầu tiên của Trang 5 chỉ vì hàng 23 trên Trang 2 đã bị xóa trong thời gian chờ đợi. Các hàng cũng không biến mất một cách bí ẩn giữa các trang. Những điểm bất thường này thường xảy ra với phương pháp dựa trên row_number, nhưng giải pháp dựa trên tập hợp khóa thực hiện tốt hơn nhiều trong việc tránh chúng.
  • nhanh :tất cả các hoạt động có thể được giải quyết bằng cách định vị hàng nhanh chóng, sau đó quét phạm vi theo hướng mong muốn

Tuy nhiên, cách tiếp cận này khó để thực hiện, khó hiểu đối với lập trình viên trung bình và không được hỗ trợ bởi các công cụ.

Điều khiển số hàng

Đây là cách tiếp cận phổ biến được giới thiệu với các truy vấn Linq:

select ...
from (
  select ..., row_number() over (...) as rn
  from table)
where rn between @firstRow and @lastRow;

(hoặc một truy vấn tương tự sử dụng TOP) Cách tiếp cận này dễ dàng để triển khai và được hỗ trợ bởi các công cụ (cụ thể là bởi các toán tử Linq .Limit và .Take). Nhưng cách tiếp cận này được đảm bảo để quét chỉ mục để đếm các hàng. Cách tiếp cận này thường hoạt động rất nhanh đối với trang 1 và dần dần chậm lại khi cách tiếp cận chuyển sang số trang ngày càng cao.

Như một phần thưởng, với giải pháp này, rất dễ dàng thay đổi thứ tự sắp xếp (chỉ cần thay đổi mệnh đề OVER).

Nhìn chung, với sự dễ dàng của các giải pháp dựa trên ROW_NUMBER (), sự hỗ trợ mà họ có từ Linq, sự đơn giản để sử dụng các đơn đặt hàng tùy ý cho tập dữ liệu vừa phải ROW_NUMBER giải pháp dựa trên là phù hợp. Đối với các tập dữ liệu lớn và rất lớn, ROW_NUMBER () có thể xảy ra các vấn đề nghiêm trọng về hiệu suất.

Một điều khác cần xem xét là thường có một mô hình truy cập nhất định. Thường thì một số trang đầu tiên rất nóng và các trang sau 10 về cơ bản không bao giờ được xem (ví dụ:các bài đăng gần đây nhất). Trong trường hợp này, hình phạt xảy ra với ROW_NUMBER () cho việc truy cập các trang dưới cùng (các trang hiển thị phải đếm số lượng lớn các hàng để có được hàng kết quả bắt đầu) có thể được bỏ qua.

Và cuối cùng, phân trang bộ phím rất tuyệt vời để điều hướng từ điển, điều mà ROW_NUMBER () không thể đáp ứng dễ dàng. Điều hướng từ điển là nơi thay vì sử dụng số trang, người dùng có thể điều hướng đến một số neo nhất định, chẳng hạn như các chữ cái trong bảng chữ cái. Ví dụ điển hình là một liên hệ Rolodex như thanh bên, bạn nhấp vào M và bạn điều hướng đến tên khách hàng đầu tiên bắt đầu bằng M.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Thành thạo việc sử dụng danh sách dừng với tìm kiếm toàn văn bản trên SQL Server (FTS)

  2. Ràng buộc duy nhất trong SQL Server là gì - Hướng dẫn sử dụng SQL Server / TSQL Phần 95

  3. Có thể thực thi một tệp văn bản từ truy vấn SQL không?

  4. Thủ thuật nhanh và tốt nhất để khôi phục tệp SQL Server MDF

  5. Cách tự động hóa việc thu thập dữ liệu về sự phát triển của cơ sở dữ liệu SQL Server