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

Cách hiệu quả để nhận @@ rowcount từ một truy vấn bằng cách sử dụng row_number

Trong nhiều năm, rất nhiều nhà phát triển đã đổ mồ hôi vào việc phân trang các tập kết quả một cách hiệu quả. Tuy nhiên, không có một câu trả lời - nó phụ thuộc vào trường hợp sử dụng của bạn. Một phần của trường hợp sử dụng là tải trang của bạn một cách hiệu quả, một phần là tìm ra có bao nhiêu hàng trong một tập kết quả hoàn chỉnh. Vì vậy, xin lỗi nếu tôi hơi lạc vào phân trang, nhưng cả hai kết hợp chặt chẽ với nhau trong tâm trí tôi.

Có rất nhiều chiến lược, hầu hết đều không tốt nếu bạn có bất kỳ loại khối lượng dữ liệu nào &không phù hợp với trường hợp sử dụng. Mặc dù đây không phải là danh sách đầy đủ, nhưng sau đây là một số tùy chọn .....

Chạy riêng Count(*)

  • chạy một truy vấn riêng biệt thực hiện một "số lượng chọn (*) từ MyTable" đơn giản
  • đơn giản và dễ dàng cho một chiếc bàn nhỏ
  • tốt trên một bảng lớn chưa được lọc, hẹp hoặc có chỉ mục nhỏ gọn không phân cụm mà bạn có thể sử dụng
  • hỏng khi bạn có WHERE/JOIN phức tạp tiêu chí vì chạy WHERE/JOIN đắt gấp đôi.
  • chia nhỏ trên một chỉ mục rộng vì số lần đọc tăng lên.

Kết hợp ROW_Number() OVER()COUNT(1) OVER(PARTITION By 1)

  • Điều này được đề xuất bởi @RBarryYoung. Nó có lợi ích là vệ sinh đơn giản và rất linh hoạt.
  • Mặt trái của nó là có rất nhiều lý do khiến việc này có thể trở nên cực kỳ tốn kém một cách nhanh chóng.
  • Ví dụ:trong DB mà tôi hiện đang làm việc có một bảng Phương tiện với khoảng 6000 hàng. Nó không đặc biệt rộng, có PK nhóm số nguyên và cũng như một chỉ mục duy nhất nhỏ gọn. Tuy nhiên, một COUNT(*) OVER(PARTITION BY 1) as TotalRows kết quả là ~ 12.000 lần đọc. So sánh nó với một SELECT COUNT(*) FROM Media đơn giản - 12 lần đọc. Wowzers.

Bảng tạm thời / Bảng biến

  • Có rất nhiều chiến lược sử dụng tập hợp kết quả và chèn các khóa hoặc phân đoạn kết quả có liên quan vào bảng tạm thời / biến bảng.
  • Đối với các tập hợp kết quả có kích thước vừa / nhỏ, điều này có thể mang lại kết quả tuyệt vời.
  • Loại chiến lược này hoạt động trên hầu hết mọi nền tảng / phiên bản của SQL.
  • Thao tác trên một tập hợp kết quả nhiều lần (thường là một yêu cầu) cũng dễ dàng.
  • Mặt trái là khi làm việc với các tập kết quả lớn ... việc chèn một vài triệu hàng vào bảng tạm thời có chi phí.
  • Vấn đề phức tạp hơn, trong điều kiện hệ thống có âm lượng lớn, áp suất lên TempDB có thể là một yếu tố khá nguy hiểm và các bảng tạm thời đang hoạt động hiệu quả trong TempDB.

Tổng Gaussian / Số hàng đôi

  • Ý tưởng này dựa trên tập hợp con của một cái gì đó mà nhà toán học Gauss đã tìm ra (cách tính tổng một chuỗi số). Tập hợp con là cách tính số hàng từ bất kỳ điểm nào trong bảng.
  • Từ một chuỗi số (Row_Number() ) số hàng từ 1 đến N là (N + 1) - 1 . Giải thích thêm trong các liên kết.
  • Công thức có vẻ giống như chỉ bằng N, nhưng nếu bạn kiên trì với công thức, một điều thú vị sẽ xảy ra, bạn có thể tính ra số hàng từ một trang ở giữa bảng.
  • Kết quả thực là bạn ROW_Number() OVER(Order by ID)ROW_Number() OVER(Order by ID DESC) sau đó tính tổng hai số và trừ đi 1.
  • Sử dụng bảng Phương tiện của tôi làm ví dụ, số lần đọc của tôi đã giảm từ 12.000 xuống còn khoảng 75.
  • Trong một trang lớn hơn, bạn đã kết thúc việc lặp lại dữ liệu nhiều lần, nhưng bù lại số lần đọc có thể đáng giá.
  • Tôi chưa thử nghiệm điều này trên quá nhiều trường hợp, vì vậy, nó có thể bị hỏng trong các trường hợp khác.

Top (@n) / SET ROWCOUNT

  • Đây không phải là các chiến lược cụ thể theo từng phần, nhưng là các tối ưu hóa dựa trên những gì chúng tôi biết về trình tối ưu hóa truy vấn.
  • Một cách sáng tạo bằng cách sử dụng Top (@n) [top có thể là một biến trong SQL 2008] hoặc SET ROWCOUNT có thể giảm tập hợp làm việc của bạn ... ngay cả khi bạn đang kéo trang giữa của tập kết quả, bạn vẫn có thể thu hẹp kết quả
  • Những ý tưởng này hoạt động do hành vi của trình tối ưu hóa truy vấn ... gói dịch vụ / hotfix có thể thay đổi hành vi (mặc dù có thể là không).
  • Trong các trường hợp chứng nhận, SET ROWCOUNT có thể chính xác một chút
  • Chiến lược này không giải thích cho việc nhận được toàn bộ số hàng, chỉ giúp phân trang hiệu quả hơn

Vậy nhà phát triển phải làm gì?

Đọc người đàn ông tốt của tôi, đọc. Đây là một số bài báo mà tôi đã dựa vào ...

Hy vọng điều đó sẽ hữu ích.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Sử dụng OBJECT_NAME () để lấy tên đối tượng từ object_id của nó trong SQL Server

  2. Làm thế nào để tạo một chỉ mục duy nhất trên một cột NULL?

  3. SQL - Thủ tục lưu trữ cuộc gọi cho mỗi bản ghi

  4. .NET SQL chèn chậm so với JDBC? (JDBC nhanh hơn gấp 4 lần)

  5. Lặp lại hàng N lần theo giá trị cột