2017-12-22 179 views
5

Tôi có một mạng lưới cơ bản với phân trang được bật trong ứng dụng web của tôi. Lưới này đang được phổ biến bởi dữ liệu SQL thông qua một API Web sử dụng Dapper. Trong bộ điều khiển API của tôi, tôi đang chạy hai truy vấn riêng biệt: một để trích xuất các hàng (được hiển thị trong lưới của tôi) và một để lấy tổng số bản ghi (để hiển thị trong điều khiển phân trang của tôi). Và điều này hoạt động. Tuy nhiên, tôi đang cố gắng tối ưu hóa các truy vấn của mình.Tôi có thể truy xuất các hàng được phân trang và tổng số trong một truy vấn không?

truy vấn đầu tiên của tôi, mà chiết xuất các hàng, trả về chỉ có 50 hàng tại một thời điểm (sử dụng OFFSETFETCH, để cung cấp phân trang:

SELECT DISTINCT T_INDEX.* 
FROM T_INDEX 
INNER JOIN T_INDEXCALLER ON T_INDEX.IndexId = T_INDEXCALLER.IndexId 
WHERE... --a fairly complex WHERE statement 
ORDER BY CallTime DESC 
OFFSET (@offset) ROWS FETCH NEXT 50 ROWS ONLY 

truy vấn thứ hai của tôi chiết xuất số lượng của tất cả các hàng, nhưng sử dụng các bảng tương tự, cùng tham gia, và cùng WHERE khoản:.

SELECT COUNT(DISTINCT T_INDEX.IndexId) 
FROM T_INDEX 
INNER JOIN T_INDEXCALLER ON T_INDEX.IndexId = T_INDEXCALLER.IndexId 
WHERE... --the same fairly complex WHERE statement 

Như tôi đã nói, công trình này và nó t akes khoảng 2,5 giây cho mỗi truy vấn, trong tổng số hơn 5 giây. Thời gian trễ không phải là kết thúc của thế giới, bằng bất kỳ phương tiện nào, nhưng tôi muốn cắt giảm thời gian đó một nửa.

Tôi muốn biết nếu có bất kỳ cách nào để truy xuất 50 hàng truy lục tổng số TẤT CẢ các hàng trong một truy vấn. Tôi nhận ra rằng hai truy vấn này đang làm hai việc riêng biệt. Nhưng suy nghĩ của tôi là có "có thể" là một cách để tinh chỉnh hai truy vấn này và kết hợp chúng thành một, vì các bảng, tham gia và mệnh đề WHERE giống nhau giữa hai truy vấn.

Trả lời

1

Bạn có thể cung cấp cho truy vấn này thử xem:

SELECT * 
FROM (
    SELECT *, COUNT(*) OVER() AS cnt 
    FROM (
     SELECT DISTINCT T_INDEX.*, 
     FROM T_INDEX 
     INNER JOIN T_INDEXCALLER ON T_INDEX.IndexId = T_INDEXCALLER.IndexId 
     WHERE... --a fairly complex WHERE statement 
    ) AS t1) AS t2 
ORDER BY CallTime DESC 
OFFSET (@offset) ROWS FETCH NEXT 50 ROWS ONLY 

Bạn có thể đơn giản hóa các truy vấn trên tùy thuộc vào những gì xác định một kỷ lục khác biệt trong tập kết quả.

+0

Tôi nghĩ rằng đây có thể là những gì tôi đang tìm kiếm. Trên cặp vợ chồng đầu tiên của tôi cố gắng, nó xuất hiện để được làm việc tuyệt vời. Tôi sẽ làm một số tinh chỉnh hơn. –

0
SELECT DISTINCT T_INDEX.*, 
     (SELECT COUNT(DISTINCT T_INDEX.IndexId) FROM T_INDEX 
      INNER JOIN T_INDEXCALLER ON T_INDEX.IndexId = 
      T_INDEXCALLER.IndexIdAS) AS TotalCount 
FROM T_INDEX 
INNER JOIN T_INDEXCALLER ON T_INDEX.IndexId = T_INDEXCALLER.IndexId 
WHERE... --a fairly complex WHERE statement 
ORDER BY CallTime DESC 
OFFSET (@offset) ROWS FETCH NEXT 50 ROWS ONLY 
+0

Hmmm, hấp dẫn.Nhưng tôi nhận được '1' cho' TotalCount' cho mỗi hàng –

+0

những gì bạn cần chính xác? Khi bạn yêu cầu tổng số hồ sơ –

+0

Tổng số bản ghi. Như trong tổng số hồ sơ cho toàn bộ tập dữ liệu. –

0

Tôi đề xuất một giải pháp khác: không thực hiện tối ưu hóa mù này.

Bạn đang cố gắng may mắn - điều đó là không hợp lý.

Chúng không giống nhau và chúng có thể được tối ưu hóa riêng lẻ. Nhưng điều quan trọng hơn là cả hai truy vấn của bạn được thực hiện trong 2.5 giây trông có vẻ lạ đối với các truy vấn chỉ bằng cách tham gia đơn giản và nhiệm vụ đơn giản là nhận được 50 records hoặc count all. Tôi biết nó phụ thuộc vào kích thước của bảng và phần cứng máy chủ của bạn, nhưng vẫn còn.

Vì vậy, tôi nghĩ rằng bạn có thể tối ưu hóa cả hai người trong số họ và sẽ không cần phải "hợp nhất" chúng thành một.

Tôi sẽ xem xét kế hoạch thực hiện truy vấn trước. Tôi khá chắc chắn nó có thể được tăng tốc rất nhiều. Vì vậy, vui lòng thêm các kế hoạch truy vấn vào câu hỏi của bạn.

Nhưng ngay cả khi không truy vấn tôi đã có một số câu hỏi sau:

  • tại sao distinct?
  • bạn có chỉ mục trên T_INDEX.CallTime không?
+0

Tôi đánh giá cao phản hồi của bạn. Và có, tôi chắc chắn có một cách để tối ưu hóa truy vấn của tôi bằng các phương pháp khác. Đây là một phát bắn trong bóng tối để nói. Để trả lời các câu hỏi của bạn, tôi đang sử dụng 'khác biệt' vì tham gia vào truy vấn của tôi. Có một mối quan hệ một-nhiều ở đó, và tôi lấy ra các hàng cha, trong đó bất kỳ hàng nào trong các hàng con khớp với mệnh đề 'where'. Và tôi muốn đếm số hàng cha, chứ không phải các hàng con. –

+0

Tôi không có chỉ mục trên 'T_INDEX.CallTime'. Tôi sẽ thử thêm nó. –

+0

Để làm phức tạp thêm vấn đề, tôi đang thực hiện tìm kiếm văn bản giả (sử dụng phép đối chiếu nhị phân) trên hàng con, đó là lý do chính tôi muốn tìm hiểu xem tôi có thể truy vấn một lần để nhận được những gì tôi cần. Có khoảng 1 triệu hàng trong 'T_INDEXCALLER'. –

Các vấn đề liên quan